Глава 1. Установка и запуск Borland Pascal

Ваш пакет Borland Pascal включает в себя пять различных вер-

сий Borland Pascal:

* BP.EXE, интегрированную среду разработки программ (IDE),

которая работает в защищенном режиме DOS и генерирует

прикладные программы DOS реального режима, Windows и DOS

защищенного режима.

* BPW.EXE, интегрированную среду, которая работает под

Windows и генерирует прикладные программы DOS реального

режима, Windows и DOS защищенного режима.

* TURBO.EXE, интегрированную среду, которая работает в ре-

альном режиме DOS и генерирует только прикладные программы

DOS реального режима.

* BPC.EXE, компилятор, работающий в режиме командной строки

в защищенном режиме DOS и генерирующий прикладные програм-

мы DOS реального режима, Windows и DOS защищенного режима.

* TPC.EXE компилятор, работающий в режиме командной строки в

реальном режиме DOS и генерирующий только прикладные прог-

раммы DOS реального режима.

Borland Pascal поставляется с автоматической программой ус-

тановки, которая называется INSTALL. Из-за использования методов

упаковки файлов вы должны воспользоваться данной программой, а не

просто скопировать на свой жесткий диск файлы Borland Pascal.

Программа INSTALL автоматически копирует и распаковывает файлы

Borland Pascal и Borland Pascal for Windows.

Мы предполагаем, что вы уже знакомы с командами DOS. Напри-

мер, для создания резервных копий своих дистрибутивных дискет

(купленных вами дискет) вам потребуется команда DISKCOPY. Когда

вы получите дискеты, сделайте их полную рабочую копию, а оригина-

лы сохраните затем в надежном месте.

Данная глава содержит информацию по следующим вопросам:

* установка Borland Pascal и Borland Pascal for Windows в

вашей системе;

* доступ к файлу README;

* доступ к файлу HELPME!.DOC;

* использование примеров программ Borland.

Использование программы Install

Кроме выполнения других функций программа Install распознает

используемое аппаратное обеспечение и настраивает соответствующим

образом Borland Pascal. Она также автоматически создает необходи-

мые каталоги и переписывает файлы с ваших дистрибутивных дисков

на жесткий диск. Ее действия говорят сами за себя, а в приведен-

ном ниже тексте сообщается все, что вам нужно знать.

Чтобы установить Borland Pascal, сделайте следующее:

1. Вставьте установочную дискету (дискету 1) в дисковод A.

Наберите следующую команду, затем нажмите клавишу Enter:

A: INSTALL

2. Нажмите Enter, когда выведется экран установки.

3. Следуйте подсказкам.

4. Программе Install для записи временных файлов перед их

распаковкой требуется пространство на диске. В начальном

экране INSTALL перечисляются требования к пространству на

диске; если его недостаточно, выйдите из Install и осво-

бодите необходимое пространство. После завершения работы

Install эти временные файлы будут удалены.

5. В конце установки вам может потребоваться добавить в файл

CONFIG.SYS следующую строку:

FILES = 20

а в файл AUTOEXEC.BAT следующую строку:

PATH = C:\BP\BIN

(или модифицируйте оператор PATH, если он уже имеется).

Примечание: Если вы смените используемый по умолчанию

каталог, вам нужно изменить установку PATH.

Когда вы завершите работу, программа Install напомнит вам,

что нужно прочесть файл README, который содержит последнюю инфор-

мацию о деталях имеющегося у вас издания данной версии Borland

Pascal.

Программа Install и Windows

В следующий раз, когда вы запустите Microsoft Windows (после

выхода из программы просмотра файла README), выведется запрос,

хотите ли вы создать в администраторе программ программную груп-

пу Borland Pascal. Если вы выберете утвердительный ответ, Yes,

Windows создает программную группу, содержащую пиктограммы для

программ и утилит Borland Pascal и Borland Pascal for Windows.

Программа Install предполагает, что Windows устанавливается

в каталоге, который вы задали как каталог Windows в процессе ус-

тановки. Она предполагает также, что администратор программ за-

пускается автоматически как "оболочка" Windows при запуске

Windows. Если вы используете программную оболочку, отличную от

администратора программ, то вам может потребоваться отредактиро-

вать файл SYSTEM.INI в каталоге Windows и включить в него строку:

SHELL=PROGMAN.EXE

В противном случае при первоначальном открытии Windows и по-

пытке Borland Pascal создать новую группу администратора программ

вы получите сообщение, говорящее об "отсутствии связи с админист-

ратором программ". После того как Borland Pascal for Windows и

другие инструментальные средства будут установлены в группе адми-

нистратора программ, вы можете проверить эти установки и, если

хотите, переустановить их в альтернативной командной оболочке.

Запуск Borland Pascal

Для запуска Borland Pascal перейдите в созданный программой

Install подкаталог Borland Pascal BIN. Обычно этим каталогом яв-

ляется каталог C:\BP\BIN. Для запуска интегрированной среды защи-

щенного режима наберите:

BP

Примечание: Об интегрированной среде Windows рассказы-

вается ниже.

Файлы DPMI16BI.OVL и RTM.EXE должны присутствовать в ката-

логе по текущему маршруту, в противном случае BP.EXE не запустит-

ся.

Чтобы запустить интегрированную среду IDE, работающую в ре-

альном режиме, наберите:

TURBO

Защищенный режим и память

Интегрированная среда DOS защищенного режима, компилятор ре-

жима командной строки и другие инструментальные средства защищен-

ного режима используют интерфейс защищенного режима DOS, что дает

вам доступ ко всей памяти компьютера. Кроме того, вы можете ис-

пользовать Borland Pascal для написания своих собственных прило-

жений, работающих в защищенном режиме. Интерфейс защищенного ре-

жима полностью прозрачен для пользователя, и за немногими возмож-

ными исключениями вам не нужно о нем думать.

DPMIINST

Одним таким исключением может быть ситуация, когда вы запус-

каете Borland Pascal самый первый раз. Для определения того, как

разрешить использование защищенного режима на вашем компьютере,

Borland Pascal использует внутреннюю базу данных характеристик

различных машин и соответствующим образом настраивается. Если на

вашей машине более старый микропроцессор, чем 80286, то Borland

Pascal может его не распознать. При запуске Borland Pascal вы

увидите следующее сообщение:

Machine not in database (RUN DPMIINST)

(Машины нет в базе данных, запустите DPMIINST)

Если вы получили это сообщение, просто запустите программу

DPMIINST, набрав DPMIINST в ответ на подсказку DOS.

Для определения наилучшего способа разрешения защищенного

режима DPMIINST выполняет на вашей машине последовательность тес-

тов и автоматически конфигурирует соответствующим образом Borland

Pascal. После выполнения программы DPMIINST вам больше не потре-

буется ее запускать.

Некоторые администраторы памяти, драйверы устройств и рези-

дентные в памяти программы (TSR) могут нарушать способность

DPMIINST анализировать ваш компьютер. Если выполнение DPMIINST

завершается неудачно, временно запретите или удалите эти програм-

мы. Это дает DPMIINST неограниченный доступ, который необходим ей

для определения наилучшего пути перехода в защищенный режим.

Переменная DPMIMEM

По умолчанию интерфейс DPMIMEM Borland Pascal распределяет

для своего использования всю доступную дополнительную и расширен-

ную память. Если вы не хотите распределять всю доступную память

для ядра DPMIMEM, вы можете установить переменную операционной

среды таким образом, чтобы задать максимальный объем используемой

памяти. Эту переменную можно ввести непосредственно в ответ на

подсказку DOS или задать в виде строки файла AUTOEXEC.BAT, ис-

пользуя следующий синтаксис:

SET DPMIMEM=MAXMEM nnnn

где nnnn - объем памяти в килобайтах.

Например, если у вас есть система с 4 мегабайтами памяти и

вы хотите, чтобы ядро DPMIMEM использовало 2 мегабайта, оставляя

2 мегабайта свободными, переменную DPMIMEM следует установить

следующим образом:

SET DPMIMEM=MAXMEM 2000

RTMRES

RTMRES выполняет предзагрузку DPMI-сервера. Он разрешает

DPMI и порождает командный процессор DOS. Предзагрузка DPMI-сер-

вера позволяет вам загружать инструментальные средства Borland

Pascal, работающий в защищенном режиме, такие как BP, BPC, TASMX

и т.д. несколько быстрее. Для выхода из командного процессора на-

берите EXIT.

RTMRES особенно полезен, если вы используете BPC - компиля-

тор командной строки, работающий в защищенном режиме DOS. Каждый

раз, когда вы его вызываете, загружается DPMI-сервер. Если вы

предварительно запустили RTMRES, то сервер уже присутствует, и

компилятор режима командной строки загружается быстрее.

Borland Pascal и расширенная память

После загрузки ядра DPMI (выполнением BP или с помощью ути-

литы RTMRES) интегрированная интерактивная среда Borland Pascal

взаимодействует с DPMI-сервером черед администратор этапа выпол-

нения Borland (RTM.EXE) для распределения памяти таким образом,

что сможет загружаться и выполняться интегрированная среда IDE.

По умолчанию IDE использует всю расширенную память, зарезервиро-

ванную ядром DPMI.

Запуск Borland Pascal for Windows

Чтобы запустить Borland Pascal for Windows, щелкните кнопкой

"мыши" на пиктограмма Borland Pascal for Windows администратора

программ. Из Windows вы можете также запускать две интегрирован-

ные интерактивные среды для DOS; их пиктограммы можно найти в ад-

министраторе программ.

Запуск BP.EXE в расширенном режиме Windows 386

Интегрированная среда защищенного режима DOS должна прекрас-

но работать, если вы запускаете Windows в расширенном режиме 386.

Переменную DPMIMEM вам устанавливать не потребуется; вместо этого

используйте для конфигурирования объема памяти, которую вы хотите

отвести для использования Borland Pascal, файл PIF Borland Pascal

for Windows (BP\BIN\BP.PIF).

Запуск BP.EXE в стандартном режиме Windows

Предварительная загрузка DPMI-сервера позволяет вам запус-

кать инструментальные средства защищенного режима (BP, BPC, TASMX

и т.д.) в Windows в стандартном режиме DOS. Для этого запустите

RTMRES.EXE (как описано выше). Использование RTMRES.EXE в сочета-

нии с Windows всегда устанавливает переменную DPMIMEM в объем па-

мяти, меньший максимального. Это обеспечивает в Windows наличие

достаточного объема физической памяти для работы.

Если вы работаете под управлением оболочки RTMRES, то не

сможете запустить Windows в улучшенном режиме 386, поскольку

DPMI-сервер по умолчанию распределяет всю расширенную память для

своего собственного использования. Вам нужно сначала выйти из

оболочки, а затем запустить Windows или использовать для ограни-

чения объема памяти, распределяемой DPMI-сервером, переменную

DPMIMEM.

Запуск BP.EXE в окне Windows DOS

Если в окне Windows DOS вы выберите запуск интегрированной

среды защищенного режима, то вам нужно сначала модифицировать

файл DOSPRMPT.PIF (который можно найти в каталоге Windows), бла-

годаря чему IDE защищенного режима сможет использовать расширен-

ную память.

Откройте файл DOSPRMPT.PIF с помощью редактора PIF и укажите

объем расширенной памяти, который вы хотите использовать в интег-

рированной интерактивной среде защищенного режима. Если вы не

вполне знакомы с работой редактора PIF, см. "Руководство пользо-

вателя по Microsoft Windows".

Жидкокристаллические и плазменные экраны

Если у вас имеется портативный компьютер с жидкокристалли-

ческим ли плазменным дисплеем, то Borland Pascal следует запус-

тить с параметром запуска /L. Наберите:

BP /L

или

TURBO /L

Хотя вы всегда можете запустить Borland Pascal таким спосо-

бом, в IDE также можно настроить конфигурацию на использование

черно-белого экрана, используя для этого диалоговое окно Optionі

EnviromentіStartup. Выберите параметр LCD Color Set.

Файл README

Файл README содержит последнюю информацию, которая может от-

сутствовать в документации.

Borland Pascal автоматически помещает вам в файл README,

когда вы выполняете программу Install. Чтобы получить доступ к

файлу README позднее, вы можете использовать программу README

Borland Pascal, набрав в командной строке DOS следующие команды:

CD \BP

README

Файлы FILELIST.DOC и HELPME!.DOC

Ваш установочный диск содержит файл с именем FILELIST.DOC, в

котором перечислены все файлы, содержащиеся на дистрибутивных

дискетах, и даны краткие описания каждого из них, и файл

HELPME!.DOC, содержащий ответы на вопросы, с которыми обычно

сталкиваются пользователи. Если вы встретитесь с трудностями, об-

ратитесь к файлу HELPME!.DOC. Для просмотра файлов FILELIST.DOC и

HELPME!.DOC вы можете использовать программу README. Наберите в

командной строке следующее:

README HELPME!.DOC

или

README FILELIST.DOC

Примеры программ

Пакет Borland Pascal включает в себя большое количество при-

мером программ в исходном коде как для DOS, так и для Windows.

Эти программы находятся в подкаталогах каталога EXAMPLES, создан-

ного программой Install. Каталог EXAMPLES содержит также подката-

логи других инструментальных средств и утилит, поставляемых с

Borland Pascal (таких как Turbo Assembler, Turbo Debugger и

Resource Workshop). Потратьте немного времени и просмотрите эти

каталоги. Вы увидите, сколько для вас предусмотрено примеров

программ.


Глава 2. Что нового в Borland Pascal

Borland Pascal with Objects - это профессиональная объект-

но-ориентированная система программирования для реального и защи-

щенного режима DOS и Windows. Если вы работаете с программными

продуктами Turbo Pascal или Turbo Pascal for Windows, то из дан-

ной главы вы узнаете о новых средствах Borland Pascal и о том,

где найти информацию о них.

Три интегрированных интерактивных среды разработки программ

Borland Pascal предоставляет вам три интегрированных инте-

рактивных среды разработки программ (IDE):

* BP.EXE, интегрированную среду разработки программ, которая

работает в защищенном режиме DOS и генерирует по вашему

выбору прикладные программы DOS реального режима, Windows

и DOS защищенного режима. IDE защищенного режима означает,

что каждое ваше очень большое приложение будет иметь для

компиляции достаточно памяти.

* BPW.EXE, интегрированную среду, которая работает под

Windows и генерирует по вашему выбору прикладные программы

DOS реального режима, Windows и DOS защищенного режима.

* TURBO.EXE, интегрированную среду, которая работает в ре-

альном режиме DOS и генерирует только прикладные программы

DOS реального режима, работающие только на процессорах

80х86.

Примечание: Для работы IDE DOS защищенного режима ваш

компьютер должен иметь процессор 80286 или старше и не ме-

нее 2 мегабайт памяти.

Об интегрированных средах для DOS рассказывается в Главе 4

"Программирование в интегрированной интерактивной среде для DOS".

О специальных средствах интегрированной среды для Windows вы мо-

жете узнать из Главы 5 "Программирование в интегрированной инте-

рактивной среде для Windows".

Новые средства IDE

В перечисленных IDE вы можете найти следующие новые средс-

тва:

* Два средства просмотра объектов ObjectBrowser - одно в IDE

для DOS защищенного режима, другое в IDE для Windows. С

помощью ObjectBrowser вы можете просматривать в своей

программе объекты и модули, проверять свой исходный код,

получать полные перекрестные ссылки на каждый используемый

в программе идентификатор и видеть свою программу с новой

позиции. Об ObjectBrowser для DOS и Windows в данной книге

рассказывается ниже.

* Выделение синтаксиса. Во всех интегрированных средах в

программах используется цветовое выделение элементов кода,

благодаря чему вы можете быстро идентифицировать фрагменты

исходного кода. В IDE для Windows вы можете также исполь-

зовать синтаксические элементы, выделяемые жирным, наклон-

ным шрифтом или подчеркиванием. Во всех IDE вы можете пе-

чатать синтаксически выделенный код. О выделении синтакси-

са рассказывается в Главе 4 "Программирование в интегриро-

ванной интерактивной среде для DOS" и в Главе 5 "Програм-

мирование в интегрированной интерактивной среде для

Windows".

* Оперативная полоса SpeedBar в IDE для Windows. Эта опера-

тивная полоса предоставляет быстрый способ выбора команд

меню и других действий с помощью "мыши". Вы можете по сво-

ему выбору выводить ее горизонтально, вертикально или в

виде свободной палитры, либо даже выключить ее полностью.

* В редакторах для DOS и Windows имеются средства Undo (От-

мена) и Redo (Повтор). Если вы сделаете в процессе редак-

тирования ошибку, нажмите Undo, и ваша ошибка исчезнет.

Нажмите Redo - и она появится вновь.

* Меню инструментальных средств Tools. Инструментальные

средства и утилиты, поставляемые с Borland Pascal, вы мо-

жете запускать непосредственно из IDE. В IDE для DOS в ме-

ню Tools вы можете добавить свои собственные утилиты и из-

менить по своему усмотрению оперативные клавиши. О меню

Tools IDE для DOS и о меню Tools IDE для Windows рассказы-

вается в Главе 4.

* Окно сообщений Messages в IDE для DOS. Окно Messages вы

можете использовать для вывода сообщений из таких утилит

как GREP. Вы можете выбрать редактирование программной

строки со ссылкой на сообщение или отслеживать сообщения в

исходном коде при просмотре сообщений.

* Локальные меню во всех интегрированных средах. Простым на-

жатием правой кнопки "мыши" или клавиш Alt+F10 вы можете

вывести локальное меню со списком команд, относящихся к

активному окну.

* Информация об идентификаторах сохраняется от одного сеанса

к другому. Это позволяет после выхода и перезапуска IDE

вам просматривать, отлаживать или выполнять программы без

перекомпиляции.

* Информация об идентификаторах сохраняется от одной до дру-

гой компиляции. Если вы успешно скомпилируете программу,

измените исходный код, перекомпилируете ее, и компиляция

завершится неудачно, информация об идентификаторах сохра-

нится с момента последней компиляции. Ее просмотр может

помочь вам выявить ошибку в исходном коде.

* В интегрированных средах для DOS поддерживаются множест-

венные устанавливаемые пользователем справочные файлы. В

справочную систему Borland Pascal вы можете загрузить до-

полнительные справочные файлы. IDE объединяет тематические

указатели вновь загруженных справочных файлов и стандарт-

ного системного тематического указателя Help.

Компилятор командной строки, работающий в защищенном режиме

Компилятор командной строки BPC.EXE, работает в защищенном

режиме, благодаря чему очень большие программы имеют достаточно

памяти для успешной компиляции. Аналогично IDE для DOS, работаю-

щей в защищенном режиме, BPC.EXE может создавать прикладные прог-

раммы реального режима DOS, Windows и защищенного режима DOS. О

компиляторе, работающем в режиме командной строки, рассказывается

в Главе 3 "Компиляторы, работающие в режиме командной строки"

"Справочного руководства программиста".

Среда разработки программ защищенного режима DOS

С помощью компиляторов командной строки BP.EXE и BPC.EXE вы

можете создавать программы, работающие в защищенном режиме DOS

без использования оверлеев. Ваши программы смогут, наконец, пре-

высить барьер реального режима DOS в 640К.

Для многих ваших программ все, что нужно сделать для созда-

ния приложения DOS защищенного режима, это выбор защищенного ре-

жима DOS в качестве целевой платформы и установка соответствующих

параметров компилятора (см. Главу 4). Возможно, вы захотите про-

честь также Главу 17 "Руководства по языку" ("Программирование в

защищенном режиме DOS"), которой вопросы, касающиеся защищенного

режима, рассматриваются более углубленно.

Динамически компонуемые библиотеки DOS

Динамически компонуемые библиотеки (DLL) традиционно были

частью разработки программ Windows. С помощью Borland Pascal вы

сможете создавать DLL для DOS.

Библиотеки DLL загружаются на этапе выполнения отдельно от

ваших файлов .EXE и могут совместно использоваться несколькими

прикладными программами. DLL для DOS работают в защищенном режиме

DOS и полностью совместимы с DLL для Windows, что позволяет вам

совместно использовать DLL для прикладных программ DOS и Windows.

О динамически компонуемых библиотеках рассказывается в Главе 11

"Динамически компонуемые библиотеки" в "Руководстве по языку".

Добавления к языку Паскаль

Borland Pascal имеет несколько новых расширения языка, об-

легчающих написание программ:

* Открытые параметры. Открытые параметры позволяют переда-

вать в процедуру или функцию строки и массивы переменных

размеров. Об этих параметрах рассказывается в Главе 9

"Процедуры и функции", в разделе "Открытые параметры" кни-

ги "Руководство по языку".

* Стандартная директива public. В Turbo Pascal 6.0 и Turbo

Pascal for Windows допускаются секции компонентов объектов

private. Borland Pascal вводит секции компонентов объектов

public, не имеющие ограничений по области действия описан-

ных в них полей и методов. Если вы находите это удобным, в

объектах можно чередовать секции компонентов public и

private. Подробнее о новой стандартной директиве public

рассказывается в разделе "Компоненты и область действия"

Главы 4 "Типы" в "Руководстве программиста".

* Зарезервированное слово inherited. Зарезервированное слово

inherited может использоваться внутри метода для ссылки на

предка объектного типа метода. См. раздел "Активизация

уточненного метода" Главы 4 "Типы" книги "Руководство по

языку".

* Параметры-константы. Процедуры и формулы могут использо-

вать параметры-константы: группе параметров предшествует

зарезервированное слово const, за которым следует тип. Па-

раметры-константы защищают от случайных присваиваний фор-

мальному параметру, и в некоторых случаях это позволяет

компилятору генерировать более эффективный код. См. раздел

"Параметры" в Главе 9 "Процедуры и функции" в "Руководстве

по языку".

* Динамические методы и таблицы динамических методов (DMT).

Если вы работали с Turbo Pascal for Windows, то уже знаете

о динамических методах и таблицах динамических методов

DMT. В Borland Pascal их могут также использовать програм-

мы для DOS.

Динамические методы отличаются от виртуальных методов спо-

собом диспетчеризации динамических методов на этапе выпол-

нения. Вместо построения для динамических методов таблицы

виртуальных методов (VMT) компилятор строит DMT. Использо-

вание DMT уменьшает потребности вашей прикладной программы

в памяти при программировании с объектами. Более подробно

о динамических методах рассказывается в разделе "Динами-

ческие методы" в Главе 4 ("Типы") "Руководства по языку".

Чтобы узнать подробности о таблицах динамических методов,

см. раздел "Таблицы динамических методов" в Главе 21

("Вопросы использования памяти") "Руководства по языку".

Улучшения в библиотеке исполняющей системы

Borland Pascal имеет три библиотеки исполняющей системы:

TURBO.TPL для программ DOS реального режима, TPW.TPL для программ

Windows и TPP.TPL для программ DOS защищенного режима.

Улучшения библиотек исполняющей системы касаются следующих

элементов:

* более быстрого ввода-вывода текстового файла;

* более быстрой функции Pos;

* оптимизации 80386 для операций умножения, деления, сдвига

влево и вправо со значениями типа Longint.

Новые подпрограммы модуля System

Модуль System содержит семь новых процедур и функций. Вы мо-

жете найти их в Главе 1 ("Справочник по библиотеке") "Справочного

руководства программиста".

* Процедура Assigned выполняет проверку и анализ того, со-

держит ли указатель или процедурная переменная nil.

* Процедура Break завершает оператор for, while или repeat.

* Процедура Continue продолжает следующие итерации оператора

for, while или repeat.

* Процедура Include включает элемент в множество.

* Процедура Exclude исключает элемент из множества.

* Функция High возвращает наивысшее значение в диапазоне ар-

гумента.

* Функция Low возвращает низшее значение в диапазоне аргу-

мента.

Новые модули

Благодаря модулю Strings программисты, использующие Turbo

Pascal for Windows, могли работать со строками с завершающим ну-

лем (в стиле Си). Теперь модуль Strings могут использовать как

программисты, работающие в Windows, так и работающие в DOS. Под-

робнее о строках с завершающим нулем рассказывается в Главе 18

"Использование строк с завершающим нулем" в "Руководстве по язы-

ку". Полную информацию о строках с завершающим нулем вы можете

получить, прочитав Главу 1 ("Справочник по библиотеке") "Справоч-

ного руководства программиста".

Программисты, работающие с Turbo Pascal for Windows, уже

знакомы с модулем WinDos. Программисты, работающие в DOS, также

могут использовать модуль WinDos для реализации операционных сис-

тем и подпрограмм обработки файлов. Чтобы выяснить, следует вам

использовать модуль WinDos или Dos, прочитайте Главу 16 "Интер-

фейс с DOS" "Руководства по языку". Все процедуры и функции под-

робно поясняются в Главе 1 ("Справочник по библиотеке") "Справоч-

ного руководства программиста".

Модуль WinAPI дает вам возможность прямого доступа к расши-

рениям DOS защищенного режима. Интерфейс WinAPI разработан как

подмножество API (интерфейс прикладных программ) Windows, чтобы

облегчить написание переносимых приложений и двоично-совместимых

DLL. О модуле WinAPI рассказывается в Главе 17 "Программирование

в DOS в защищенном режиме" "Руководства по языку". Более полную

информацию о процедурах и функциях модуля WinAPI можно найти в

Главе 1 ("Справочник по библиотеке") "Справочного руководства

программиста".

Модуль WinPrn позволяет послать информацию, выводимую вашей

программой Windows, на выбранный принтер. О печати в программах

Windows рассказывается в Главе 14 ("Ввод и вывод") "Руководства

по языку". См. также расширенные пояснения по процедурам WinPrn в

Главе 1 ("Справочник по библиотеке") "Справочного руководства

программиста".

Модуль Win31 обеспечивает интерфейс с дополнительными прог-

раммами API, которые можно найти в DLL KERNEL и USER Windows 3.1.

Приложения, использующие модуль Win31, не будут работать под

Windows 3.0. Подробности о модуле Win31 вы можете узнать в спра-

вочной системе Borland Pascal.

Остальные расширения API Windows 3.1 Borland Pascal поддер-

живает в нескольких модулях (информацию о них вы можете получить

в справочной системе Borland Pascal):

ColorDlg LZExpand ShellAPI

CommDlg MMSystem Stress

Cpl OLE TooHelp

DDEML PenWin Ver

Dlgs Print WinMem32

Новые директивы компилятора

Borland Pascal имеет пять новых директив компилятора. Под-

робнее о них рассказывается в Главе 2 ("Директивы компилятора")

"Справочного руководства программиста":

* Директива $P (открытые строковые параметры) управляет

смыслом параметров-переменных, описанных с помощью ключе-

вого слова string.

* Директива $T (указатели с проверкой типа) управляет типами

значений указателей, генерируемых операцией @.

* Директива $Q (проверка переполнения) управляет генерацией

кода проверки переполнения для отдельных арифметических

операций.

* Директива $K (эффективные вызовы) управляет генерацией эф-

фективных вызовов процедур и функций, экспортируемых при-

ложением Windows. Подробнее об обработке в Borland Pascal

эффективных вызовов рассказывается в разделе "Код входа и

выхода" Главы 22 ("Вопросы управления") "Руководства по

языку".

* Директива $Y (информация об идентификаторе) генерирует

в компилируемой программе или модуле ссылочную информацию

идентификатора, благодаря чему ObjectBrowser может выво-

дить на экран определение идентификатора и ссылочную ин-

формацию для данного программного модуля.

Усовершенствования компилятора

Кроме расширений языка Borland Pascal и добавления новых ди-

ректив компилятора, в сам компилятор также внесены улучшения:

* Компилятор позволяет выполнять более простую компоновку с

Си и ассемблером путем передачи в ваш выполняемый файл ин-

формации о номерах строк .OBJ. Таким образом, вы можете

использовать встроенные отладчик для выполнения по шагам

кода языка Си и ассемблера. См. в данной книге Главу 6

"Отладка в интегрированной среде".

* Когда правым операндом операции in является константа мно-

жественного типа, компилятор генерирует более эффективный

код. См. раздел "Встраивание констант множественного типа"

в Главе 23 ("Оптимизация кода") в "Руководстве по языку".

* Компилятор генерирует более эффективный код для малых мно-

жеств. О малых множествах подробнее рассказывается в Главе

23 ("Оптимизация кода") в "Руководстве по языку".

* Компилятор допускает неограниченную вложенность модулей.

* Оператор uses в разделе implementation модуля не вызывает

теперь циклической ссылки на модуль.

* В определенных ситуациях компилятор подавляет операции из-

быточной загрузки указателей. См. Главу 23 ("Оптимизация

кода") "Руководства по языку".

Улучшения в Turbo Vision

В Turbo Vision 2.0 в иерархию добавлены новые объекты, а к

существующим объектам добавлены некоторые новые возможности. Из-

менения существующий объектов имеют обратную совместимость, поэ-

тому существующий код Turbo Vision следует компилировать без из-

менений, а существующие потоки и ресурсы загружаются без ошибок.

В Turbo Vision 2.0 имеются некоторые новые средства. О них

рассказывается в "Руководстве по программированию с Turbo

Vision":

* Поддержка проверки допустимости данных. Ваши приложения

Turbo Vision могут обеспечить получения для обработки до-

пустимых данных.

* Кнопки с независимой фиксацией с множеством состояний.

Кнопки с независимой фиксацией могут иметь состояния, от-

личные от "выбрана" и "не выбрана". IDE защищенного режима

DOS (BP.EXE) использует кнопки с независимой фиксацией с

множеством состояний в своем диалоговом окне параметров

компилятора Compiler Options.

* Средство просмотра схемы объектов. Для вывода схем ваши

приложения могут использовать два объекта - TOutlineViewer

и TOutline. Эти объекты использует средство DOS

ObjectBrowser.

* Поддержка версий объектов в потоках. Даже если ваши объек-

ты были созданы с помощью Turbo Vision 1.0, ваши программы

все равно смогут считывать их как объекты, совместимые с

Turbo Vision 2.0.

* Новое учебное руководство и пересмотренная документация.

Вы увидите, что можно быстро изучить и освоить Turbo

Vision.

Улучшения ObjectWindows

В иерархию ObjectWindows добавлены новые объекты. К сущест-

вующим объектам также добавлены некоторые новые возможности.

Модуль WObjects больше не существует. Существующий у вас ис-

ходный код можно будет успешно перекомпилировать, если вы замени-

те каждую ссылку на WObjects модулями OWindows, ODialogs, OMemory

и Objects.

ObjectWindows содержит новые средства. Узнать о них можно,

прочитав "Руководство по программированию с использованием

ObjectWindows":

* Поддержка проверки допустимости данных. Ваши приложения

ObjectWindows могут обеспечить получение для обработки до-

пустимых данных.

* Печать объектов. Благодаря новым объектам печати выводить

данные на печать в программах ObjectWindows стало проще.

* Поддержка специализированных управляющих элементов Windows

фирмы Borland. Ваши программы Windows могут иметь вид, со-

ответствующий стандарту Borland.

Новые средства и утилиты

Если вашей целевой платформой является Windows, помочь про-

цессу разработки могут два новых средства. Прочесть о них можно в

"Руководстве по инструментальным средствам и утилитам".

* Утилита WinSight. WinSight - это инструментальное средство

отладки, которое дает вам информацию об окнах, классах и

сообщениях. Используйте ее для изучения новых приложений

Windows (ваших или чужих), чтобы увидеть как создаются и

используются окна и классы окон, и какие сообщения получа-

ют окна во время выполнения программы.

* Утилита WinSpector. С помощью WinSpector вы можете прове-

рить приложение Windows после завершения его с невосста-

навливаемой ошибкой (Unrecoverable Application Error -

UAE). Это поможет вам понять причину ошибки.

Borland Pascal также включает в себя обновленные версии сле-

дующих инструментальных средств:

* Turbo Debugger (Турбо отладчик) включает отладчик TDW, ко-

торый может отлаживать прикладные программы Windows, и

TDX, который может отлаживать прикладные программы защи-

щенного режима DOS.

* Turbo Profiler (Турбо профилировщик), который включает в

себя два профилировщика - один для программ DOS, а другой

для программ Windows.

* Turbo Assembler (Турбо ассемблер), добавляющий к коду ас-

семблера объектно-ориентированное программирование.

* Resource Workshop (Пакет разработчика ресурсов), работаю-

щий в среде Windows и способный создавать для приложений

Windows все ресурсы (диалоговые окна, курсоры, битовые

массивы, пиктограммы и т.д.).


Глава 3. Основы интегрированной среды для DOS

Borland Pascal представляет собой не только быстрый компиля-

тор Паскаля. Это эффективный компилятор, интегрированную интерак-

тивную среду которого очень легко изучать и использовать. При ра-

боте с Borland Pascal для того, чтобы создавать, отлаживать и за-

пускать программы на Паскале, вам не требуется использовать от-

дельный редактор, компоновщик, компилятор и отладчик. Все эти

средства встроены в Borland Pascal и доступны из интегрированной

интерактивной среды разработки программ (IDE).

Примечание: Если вы предпочитаете использовать компи-

лятор режима командной строки. См. Главу 3 "Компиляторы,

работающие в режиме командной строки" в "Справочном руко-

водстве программиста".

Имея пакет Borland Pascal, вы можете выбрать одну из трех

интегрированных сред:

* BP.EXE, интегрированную среду разработки программ, которая

работает в защищенном режиме DOS и генерирует прикладные

программы DOS реального режима, DOS защищенного режима и

Windows.

Чтобы запустить BP.EXE, вы должны иметь компьютер с про-

цессором 80286 или старше и не менее 2 мегабайт памяти.

Поскольку IDE работает в защищенном режиме, ее емкость ог-

раничена только объемом доступной на компьютере памятью.

* TURBO.EXE, интегрированную среду, которая работает в ре-

альном режиме DOS и генерирует только прикладные программы

DOS реального режима.

* BPW.EXE, интегрированную среду, которая работает под

Windows и генерирует прикладные программы DOS реального

режима, Windows и DOS защищенного режима.

В этой главе поясняются основы использования IDE для DOS.

Если вы уже имеете опыт работы в Windows, то вам известны

основы работы в IDE Windows, поскольку вы знаете как работает

сама Windows. Если вы не знакомы с IDE для Windows фирмы Borland,

то следует просмотреть сначала Главу 4 "Программирование в интег-

рированной среде для DOS". IDE для DOS и Windows во многом похо-

жи: в обеих средах большинство задач выполняются аналогично. Ког-

да вы поймете, как выполнять задачи по программированию в IDE,

прочитайте Главу 5 "Программирование и интегрированной интерак-

тивной среде для Windows", где рассказывается о средствах, специ-

фических в IDE для Windows и об отличиях IDE для DOS и для

Windows.

Запуск IDE

Перейдите в подкаталог Borland Pascal, созданный программой

Install. Обычно этим каталогом является каталог C:\BP\BIN. Чтобы

запустить IDE защищенного режима, введите команду:

BP

Примечание: О параметрах запуска Borland Pascal расс-

казывается в Главе 4 "Программирование в интегрированной

среде для DOS".

Файлы DPMI16BI,OVL и RTM.EXE должны находиться в текущем ка-

талоге или в каталоге, указанном в маршруте, иначе BP.EXE не за-

пустится.

Чтобы запустить IDE, работающую в реальном режиме, введите

команду:

TURBO

Компоненты интегрированной среды

Интегрированная интерактивная среда разработки программ со-

держит три видимых компонента: строку меню в верхней части экра-

на, оперативную область и строку состояния в нижней части экрана.

При активной строке меню вы увидите подсвеченный заголовок меню.

Это текущее выбранное меню.

Выбрать команды меню вы можете с помощью клавиатуры или "мы-

ши".

Выбрать команды меню с помощью клавиатуры можно следующим

образом:

1. Нажмите клавишу F10. Это активизирует строку меню.

2. Для выбора меню, которое вы хотите вывести, используйте

клавиши стрелок. Затем нажмите Enter.

Примечание: Чтобы отменить действие, нажмите клавишу

Esc.

В качестве сокращения этого шага вы можете нажать подсве-

ченную букву заголовка меню. Например, находясь в строке

меню, нажмите E для быстрого вывода меню Edit. Либо без

активизации строки меню вы можете нажать для вывода нуж-

ного меню клавишу Alt и подсвеченную букву.

3. Для выбора нужной команды меню используйте клавиши стре-

лок. Затем нажмите клавишу Enter.

Здесь снова в качестве альтернативного варианта вы можете

для выбора команды при выводе меню просто нажать подсве-

ченную букву.

При этом Borland Pascal либо выполнит команду, либо выве-

дет диалоговое окно или другое меню.

Для выбора команд можно также использовать "мышь". Для это-

го:

1. Для вывода нужного меню щелкните кнопкой "мыши", остано-

вившись на нужном заголовке меню.

2. Щелкните кнопкой "мыши" на нужной команде.

Примечание: Вы можете настроить действие Ctrl+правая

кнопка "мыши" и даже поменять действия кнопок "мыши"; вы-

берите команду OptionsіEnviromentіMouse.

Вы можете также "вытянуть" меню из заголовка вниз до команды

меню. Освободите кнопку "мыши" на нужной команде (если ваши наме-

рения изменятся, просто убедите меню обратно - команда выбрана не

будет).

Если за командой меню следует многоточие (...), выбор коман-

ды приводит к выводу диалогового окна. Если за командой указана

закрашенная стрелка (>), то эта команда приводит к другому меню

(всплывающему меню). Команда баз многоточия или стрелки указы-

вает действие, выполняемое при ее выборе.

Иногда команды меню выводятся "тусклыми", и при их выборе

ничего не происходит. Это случается, когда выбор отдельной коман-

ды в данном контексте не имеет смысла. Например, если в текущем

окне редактирования у вас нет выделенного блока, вы не сможете

вырезать, копировать или стирать текст, поскольку не указали ре-

дактору, сколько текста нужно вырезать, скопировать или стереть.

Следовательно, соответствующие команды (Cut, Copy и Clear) будут

в меню Edit тусклыми. После выделения текста в окне редактирова-

ния вы сможете выбирать эти команды.

Оперативные клавиши

Работая с клавиатурой, для доступа к строке меню и командам

вы также можете использовать множество сокращенных вариантов ко-

манд (оперативных клавиш). Перейти в основное меню и активизиро-

вать его элементы можно нажатием клавиши Alt и подсвеченной бук-

вы. Когда вы находитесь в меню, можете нажать подсвеченную букву

элемента или следующее за ней сокращение. Оперативные клавиши

можно использовать в любом месте IDE - для этого не требуется

сначала выводить меню.

Строка состояния также содержит оперативные клавиши. Для вы-

бора соответствующей команды нажмите оперативную клавишу или

щелкните "мышью" на фактическом представлении оперативной клавиши

в строке состояния.

Окна IDE

Большинство и того, что вы видите в IDE, происходит в окне.

Окно - это область экрана, которую можно перемещать, масштабиро-

вать, перекрывать, выводить без перекрытия, закрывать, открывать

и изменять ее размер.

ЪДДДДДДДДДДДДДДДДї ЪДДДДДДДДДДДї Ъї

і Для быстрого і і Заголовок і і Кнопка масштабирования і

і закрытия окна і і содержит і і содержит значок, на і

і можно щелкнуть і і название і і котором можно щелкнуть і

і "мышью" на і і данного і і мыщью для распахивания і

і блоке закрытия і і окна і і или сжатия окна і

і окна і АДДДДДДДДВДДЩ АДДДДДДДДДДДДДДДДДДДДДДДВДЩ

АДДДВДДДДДДДДДДДДЩ і і

і і і

v v v

ЙНН[Ы]ННННННННННННННННН Заголовок окна НННННННННННННННННН 3 Н[^]»

є ^ ^

є і ±

є ЪБДДДї ±

є і Каждое открытое окно имеет і ±

є і номер. Используйте Alt и # і Ы

є і для открытия окна. і ±

є АДДДДЩ ±

є ±

є ЪДДДДДДДДДДї ЪДДДДДДДї ±

є і Строка и і і Используйте полосы прокрутки і ±

є і столбец і і с "мышью" для перемещения ГДДДДДДД>±

є і позиции і і содержимого окна. і ±

є і курcора і АДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДЩ ±

є АДДДВДДДДДДЩ і ±

є і і ±

є v v v

ИН*Н1:1ННН<±±±±±±±±±±±±±±Ы±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±>ДЩ

^ ЪДДДДДї ^

ЪБДДДДДДДДДДДДї і Чтобы сделать окно больше ГДДДЩ

і Индикатор і і или меньше, буксируйте угол і

і модификации і і изменения размера. і

і файла і АДДДДДЩ

АДДДДДДДДДДДДДЩ

Рис. 3.1 Типичное окно.

При работе в IDE вы можете открыть и использовать множество

окон, но в каждый момент времени активным может быть только одно

окно. Активное окно - это то окно, в котором вы в данный момент

работаете. Любая команда, которую вы выбираете, или текст, кото-

рый вы набираете, относится только к активному окну. Однако, ес-

ли вы открыли в нескольких окнах один и тот же файл, любое дейс-

твие, применяемое к этому файлу, может отражаться на всех окнах,

содержащих его.

Существует несколько типов окон, но большинство из них со-

держат следующие элементы:

- строку заголовку;

- элемент закрытия;

- полосы прокрутки;

- угол изменения размера;

- элемент "распахивания";

- номер окна.

IDE отмечает активное окно, обрисовывая его двойной рамкой,

благодаря чему его можно легко идентифицировать на экране. Если

ваши окна перекрываются, то активное окно всегда находится перед

всеми другими ("переднее" окно).

В активном окне редактирования в левом верхнем углу выводят-

ся также значения текущей строки и столбца. Если вы модифицирова-

ли файл, слева от значений столбца и строки выводится звездочка

*.

Элемент закрытия окна находится в верхнем левом углу. Пози-

ционировав на этот элемент "мышь" и щелкнув кнопкой, вы можете

быстро закрыть данное окно (в противном случае можно выбрать ко-

манду WindowіClose). Справочное окно Help считается временным,

поэтому закрыть его можно просто нажав клавишу Esc.

Верхняя горизонтальная строка меню, строка заголовка, содер-

жит название окна и его номер. Двойной щелчок кнопкой "мыши" на

заголовке окна приводит к его "распахиванию" (увеличению до раз-

мера полного экрана) или наоборот, восстановлению предыдущего

размера, если оно уже распахнуто. Вы можете также перемещать

(буксировать) с помощью "мыши" заголовок, что приводит к переме-

щению окна.

Каждому открываемому вами окну присваивается номер (он ука-

зывается справа вверху). Нажатие клавиш Alt+0 дает вам список

всех открытых окон. Окно можно сделать активным, нажав клавишу

Alt в сочетании с номером окна. Например, если справочное окно

Help имеет номер 5, но перекрыто сейчас другим окном, нажатие

Alt+5 переводит вас в это окно (оно становится первым).

Примечание: Borland Pascal нумерует только первые 9

открытых вами окон.

В правом верхнем углу окна выводится элемент распахивания

(масштабирования) окна. Если символ в этом элементе представляет

собой стрелку вверх, то щелчок кнопкой "мыши" при позиционирова-

нии в этом элементу приведет к максимальному увеличению его раз-

мера (распахиванию). Если это двойная стрелка, то окно уже имеет

максимальный размер. В этом случае щелчок кнопкой "мыши" возвра-

щает окно к предыдущему размеру. Чтобы "распахнуть" окно с по-

мощью клавиатуры, выберите команду WindowіZoom или нажмите клави-

шу F5.

Примечание: Двойной щелчок "мышью" на строке заголовка

окна также приведет к его распахиванию или восстановлению

размера.

Полоса прокрутки - это вертикальная или горизонтальная

полоса, которая выглядит следующим образом:

<±±±±±±±±±±±±±±±±±±±±±±±±±±±Ы±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±>

Эти полосы можно использовать при работе с "мышью" для прок-

рутки содержимого окна.

* Если щелкнуть кнопкой "мыши", позиционировавшись в конце

полосы, это приведет к прокрутке на одну строку.

* Если нажать и не отпускать кнопку, прокрутка будет продол-

жаться.

* Нажатие кнопки "мыши" на затененной области в конце полосы

прокрутки (стрелки) приведет к постраничному "листанию".

* Если вы с помощью "мыши" будете перемещать (буксировать)

по полосе прокрутки скользящий маркер (здесь он отмечен

символом Ы), то содержимое окна сместится (прокрутится) в

соответствии с относительной позицией полосы прокрутки.

Примечание: Полосы прокрутки позволяют любому пользо-

вателю (использующему "мышь" или клавиатуру) видеть, как

далеко он продвинулся в файле.

В правом нижнем углу окна находится элемент изменения разме-

ра. Вы можете буксировать этот угол с помощью "мыши", увеличивая

или уменьшая размеры окна. Указанный угол отмечен одинарной, а не

двойной линией, как остальная граница окна.

Чтобы изменить размер окна с помощью клавиатуры, сделайте

следующее:

1. Используйте команду Size/Move меню Window, или нажмите

клавиши Ctrl+F5.

2. Удерживая нажатой клавишу Shift, для изменения размера

окна используйте клавиши стрелок.

Чтобы переместить окно с помощью клавиатуры, сделайте следу-

ющее:

1. Используйте команду Size/Move меню Window, или нажмите

клавиши Ctrl+F5.

2. Для перемещения окна используйте клавиши стрелок.

Управление окном

В Таблице 3.1 кратко перечислено, как можно управлять окнами

в Borland Pascal. Заметим, что для выполнения этих действий вам

не требуется "мышь" - можно прекрасно обойтись и клавиатурой.

Работа с окнами Таблица 3.1

ЪДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДї

іЧтобы: і Используйте следующие методы: і

ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДґ

іОткрыть окно і Команду Choose FileіOpen для открытияі

іредактора і файла и вывода его на экран, или клави-і

і і шу F3. і

ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДґ

іОткрыть другие окна і Выберите нужное окно из меню Window ві

і і меню Tools или Debug. і

ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДґ

іЗакрыть окно і Команду Close меню Window (или клави-і

і і ши Alt+F3), либо щелкните кнопкой "мы-і

і і ши" на элементе закрытия окна. і

ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДґ

іУвидеть предыдущее і Выберите команду WindowіPrevious или і

іокно і используйте клавиши Shift+F6. і

ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДґ

іАктивизировать окно і Щелкните кнопкой в любом месте окна,і

і і или і

і і і

і і Нажмите клавишу Alt, плюс номер окна (ві

і і верхнем правом углу окна), или і

і і і

і і Используйте команду Choose WindowіListі

і і (Выбор окнаіСписок), или нажмите клави-і

і і ши Alt+0 и выделите окно из списка, илиі

і і і

і і Используйте команду Choose WindowіNextі

і і или F6, чтобы сделать активным следую-і

і і щее (в том порядке, как вы их открыва-і

і і ли) окно. Либо нажмите клавиши Alt+F6,і

і і чтобы сделать активным предыдущее окно.і

ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДґ

іПереместить активное і Переместите с помощью "мыши" строкуі

іокно і заголовка или нажмите клавиши Ctrl+F5і

і і (WindowіSize/Move - ОкноіРазмер/Переме-і

і і щение) и используйте для позиционирова-і

і і ния окна в нужное место клавиши управ-і

і і ления курсором, после чего нажмите кла-і

і і вишу Enter. і

ЪДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДї

і Чтобы: і Используйте следующие методы: і

ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДґ

іИзменить размер і Переместите с помощью "мыши" угол из-і

іактивного окна і менения размера (или любой другойі

і і угол). Либо выберите команду Windowіі

і і Size/Move и нажмите клавишу Shift, еслиі

і і вы используете для изменения размераі

і і окна клавиши управления курсором. Послеі

і і этого нажмите клавишу Enter. Можно ис-і

і і пользовать сокращенный вариант - нажатьі

і і Ctrl+F5 и использовать клавишу Shiftі

і і совместно с клавишами управления курсо-і

і і ром (стрелки). і

ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДґ

іМасштабировать і Нажмите кнопку "мыши", позиционировав-і

іактивное окно і шись на элементе в правом верхнем уг-і

і і лу окна, или і

і і і

і і Дважды щелкните кнопкой, позициониро-і

і і вавшись в строке заголовка, или і

і і і

і і Используйте команду ChooseіWindowіZoom,і

і і или нажмите клавишу F5. і

АДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДЩ

Строка состояния

Строка состояния выводится в нижней части экрана. Она выпол-

няет следующие четыре функции:

- напоминает вам об основных и оперативных клавишах, приме-

нимых в данный момент к активному окну;

- сообщает, какие можно вместо выбора команд меню и нажатия

оперативных клавиш использовать кнопки "мыши";

- сообщает, что делает программа, например, выводит сообще-

ние "Saving имя_файла" при сохранении файла редактором;

- предлагает краткие пояснения по некоторым командам меню и

элементам диалоговых окон.

При переключении окон или изменении выполняемых действий

строка состояния изменяется. Наиболее общий вид строка состояния

имеет, когда вы записываете или редактируете программы в окне

Edit. Это показано ниже:

ЪДДДДДДДДДДДДДї

іF1 Help F2 Save F3 Open Alt+F9 Compile F9 Make F10 Menuі

АДДДДДДДДДДДДДЩ

^ ^ ^ ^ ^ ^

і і і і і і

Справка Сохранение Открытие Компиляция Формирование Меню

Рис. 3.2 Типичная строка состояния.

Диалоговые окна

Если после команды меню указано многоточие (...), то по этой

команде открывается диалоговое окно. Диалоговое окно предоставля-

ет удобный способ просмотра и установки набора параметров.

Для установок значений в диалоговом окне используется пять

основных способов управления экраном: кнопки с зависимой фиксаци-

ей, командные кнопки, кнопки с независимой фиксацией (параметры),

элементы (блоки) ввода и блоки списка. Приведем пример типичного

диалогового окна, на котором иллюстрируются некоторые из этих

элементов:

ЙН[Ы]НННННННННН Типичное диалоговое окно НННННННННННННННННННН»

є є

є є

є Блок ввода Блок списка >[±±±OK±±±]<є

є ЪДДДДДДДДДДДДДДДДДДДДДДї ЪДДДДДДДДДДДДДДДї є

є і±±±±±±±±±±±±±±±±±±±±±±ііvі іЭлемент 1 ^і є

є АДДДДДДДДДДДДДДДДДДДДДДЩ іЭлемент 2 Ыі [±Cancel±] є

є іЭлемент 3 Ыі є

є Кнопки с Кнопки с іЭлемент 4 Ыі є

є независимой зависимой іЭлемент 5 Ыі є

є фиксацией фиксацией іЭлемент 6 Ыі є

є іЭлемент 7 Іі є

є [X] Парам. 1 ( ) Парам. A іЭлемент 8 Ыі є

є [ ] Парам. 2 (.) Парам. B іЭлемент 9 vі [±±Help±±] є

є [X] Парам. 3 ( ) Парам. C АДДДДДДДДДДДДДДДЩ є

є [ ] Парам. 4 ( ) Парам. D є

є [ ] Парам. 5 є

є є

ИННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННј

Рис. 3.3 Типичное диалоговое окно.

Командные кнопки

Данное диалоговое окно содержит три стандартных командных

кнопки: OK, Cancel и Help.

* Если вы выберите OK (Подтверждение), то выбор, заданный в

диалоговом окне, будет зафиксирован в Borland Pascal.

* Если вы выбираете Cancel (Отмена), то внесенные изменения

игнорируются, а диалоговое окно остается на экране.

* Выбор Help (Справка) приводит к выводу в IDE справочной

информации по данному диалоговому окну. Клавиатурным экви-

валентом для кнопки Cancel всегда является клавиша Esc

(даже если Cancel не выводится).

Если вы работаете с "мышью", то можете просто щелкнуть кноп-

кой, позиционировавшись на нужной командной кнопке. При использо-

вании клавиатуры для активизации элемента (кнопки) можно нажимать

подсвеченные в нем буквы. Например, нажатие буквы K приводит к

выбору функциональной кнопки OK. Нажатие Tab или Shift+Tab приво-

дит к перемещению в диалоговом окне вперед или назад от одного

управляющего элемента к другому. Когда элемент становится актив-

ным, он подсвечивается. Если кнопка выбрана, чтобы задействовать

ее, просто нажмите Enter.

Командная кнопка OK диалогового окна является используемой

по умолчанию. Это означает, что для выбора данной кнопки нужно

только нажать клавишу Enter. (В системах с монохромным дисплеем

используемые по умолчанию кнопки указываются стрелками, в систе-

мах с цветным дисплеем они подсвечиваются.) Нужно помнить о том,

что переход к командной кнопке с помощью клавиши Tab делает ее

используемой по умолчанию.

Примечание: С помощью клавиши Tab вы можете выбрать

другую кнопку. Для выбора этой кнопки нажмите клавишу

Enter.

Кнопки с зависимой и независимой фиксацией

В любой момент вы можете установить любое число кнопок с не-

зависимой фиксацией. Когда вы выбираете кнопку с независимой фик-

сацией, в ней появляется символ X, показывающий, что она установ-

лена. Пустой элемент показывает, что он не установлен (выключен).

Вы можете установить (включить) кнопку с независимой фикса-

цией тремя способами:

* позиционировав на ней или на ее тексте "мышь" и щелкнув

кнопкой;

* нажимая клавишу Tab (и клавиши стрелок), пока не будет

подсвечена нужная кнопка с независимой фиксацией (или ее

группа), а затем нажав клавишу пробела.

* нажав подсвеченную в тексте букву.

На монохромных мониторах IDE отмечает активную кнопку с не-

зависимой фиксацией символом >> после этой кнопки. При нажатии

клавиши Tab символ >> перемещается к следующей группе кнопок с

зависимой или независимой фиксацией.

Примечание: Кнопки с зависимой фиксацией называются так

потому, что они действуют, как группа кнопок, где нажать в

каждый момент можно только одну кнопку (как при выборе те-

леканала). При нажатии кнопки прежняя нажатая кнопка возв-

ращается в исходное положение.

Кнопки с зависимой фиксацией отличаются от кнопок с незави-

симой фиксацией тем, что они представляют взаимоисключающие воз-

можности выбора. По этой причине кнопки с зависимой фиксацией

всегда выводятся в виде группы, и в любой группе в каждый момент

можно выбрать только одну кнопку.

Существует три способа выбора кнопок с зависимой фиксацией:

* щелкните на ней или ее тексте кнопкой "мыши";

* наберите подсвеченную в соответствующем тексте букву;

* нажимайте клавишу Tab, пока группа не будет подсвечена, а

затем для выбора конкретной кнопки используйте клавиши уп-

равления курсором: для выхода из группы с новым выбранным

функциональным переключателем нажмите клавишу Tab или

Shift+Tab.

Блоки ввода

Блок ввода - это тот элемент, в котором вы можете вводить в

свою прикладную программу текст. В элементах (полях) ввода можно

использовать большинство основных клавиш редактирования, напри-

мер, клавиши стрелок, Home, End и переключатель вставки/замены

Ins. Если вы продолжаете набирать текст при достижении конца эле-

мента ввода, его содержимое будет автоматически прокручиваться.

Если в элементе имеется больше текста, чем показано, то на концах

его выводятся закрашенные стрелки (< и >). Для прокрутки текста

вы можете позиционироваться на этих стрелках и щелкнуть кнопкой

"мыши".

Если вам требуется ввести в блоке ввода управляющие символы

(такие, как ^L или ^M), то перед этими символами нужно указать

префиксный символ ^P. Поэтому, например, для ввода ^L в поле вво-

да нужно использовать последовательность ^P^L. Это полезно приме-

нять при вводе строк.

Если справа от блока ввода указывается символ стрелки вниз,

то с этим элементом связан протокол ввода. Для просмотра протоко-

ла используйте клавишу со стрелкой вниз, а выбрав нужный элемент

из списка, нажмите Enter. В списке (протоколе) выводится весь

текст, который вы набирали в элементе ввода ранее. Если вы хотите

заново набрать текст, который уже был введен, нажмите клавишу

стрелки вниз или щелкните кнопкой "мыши" на символе "стрелка

вниз". Можно также редактировать запись из протокола. Для выхода

из списка протокола без выбора нажмите клавишу Esc.

Приведем пример протокола для элемента Find text (Поиск

текста). Если вы ранее использовали его семь раз, он может выгля-

деть следующим образом:

ЪДДДДДДДДДДДДДДДДДДДДДїЪДДДї

Text to find і±±±±±±±±±±±±±±±±±±±±±іі v і

АДДДДДДДДДДДДДДДДДДДДДЩАДДДЩ

ЙННННННННННННННННННННННННН»

є date = record ^

є Writeln(' ±

є string[7] ±

є { Ы

є AbortCode v

ИНННННННННННННННННННННННННј

Рис. 3.4 Пример протокола в диалоговом блоке.

Блоки списка

Во многих диалоговых окнах присутствует еще один компонент -

блок списка. Этот список позволяет вам просматривать и выбирать

запись из списка переменной длины, не выходя из диалогового окна.

Если в списке появляется мерцающий курсор и вы хотите что-то най-

ти, можно ввести слово (или его первые буквы), после чего IDE вы-

полнит его поиск.

Активизировать блок списка можно щелкнув на нем кнопкой "мы-

ши" или выбрав подсвеченную букву заголовка списка (либо нажать

клавишу Tab или клавиши управления курсором, пока он не будет

подсвечен). После вывода списка для его просмотра можно использо-

вать полосу прокрутки или клавиши стрелок (вверх и вниз) на кла-

виатуре.

Теперь вы познакомились с основными понятиями использования

IDE и готовы использовать интегрированную среду для разработки

прикладных программ. См. следующую главу - "Программирование в

интегрированной интерактивной среде для DOS".


Глава 4. Программирование в интегрированной интерактивной среде для DOS

При разработке прикладной программы в интегрированной среде

IDE вы можете выполнять следующие основные задачи:

* запускать IDE и выходить из нее;

* записывать и редактировать свой исходный код;

* работать с файлами (открывать, закрывать и сохранять их);

* компилировать и выполнять свои программы;

* отлаживать программы;

* просматривать исходный код;

* настраивать по своему усмотрению конфигурацию IDE;

* управлять программными проектами.

Данная глава дает основные понятия по каждой из перечислен-

ных тем, за исключением отладки программы (о которой рассказыва-

ется в Главе 6 "Отладка в интегрированной среде").

Запуск IDE и выход из нее

Перейдите в подкаталог Borland Pascal, созданный вами с по-

мощью программы Install. Обычно этим каталогом является каталог

C:\BP\BIN. Чтобы запустить IDE защищенного режима, введите коман-

ду:

BP

Файлы DPMI16BI.OVL и RTM.EXE должны находиться в текущем ка-

талоге по вашему маршруту, иначе BP.EXE не запустится.

Чтобы запустить IDE, работающую в реальном режиме, введите

команду:

TURBO

Вместе с командами для запуска IDE вы можете использовать

один или более параметров и имен файлов.

Параметры запуска

При запуске IDE вы можете указывать параметры запуска. Эти

параметры запуска имеют следующий синтаксис:

BP[/параметры][файлы]

или

TURBO[/параметры][файлы]

Указание после параметра символа + или пробела включает его,

указание символа - отключает. Например:

BP /G /P- myfile

запускает IDE, открывает окно редактирования, выводя в нем файл

MYFILE, разрешает сохранение графической памяти и запрещает пе-

реключений палитр.

Вместо символа косой черты (/) перед параметром вы можете

использовать минус (-). Например:

BP -G -P- myfile

Некоторые параметры запуска применяются только к IDE реаль-

ного режима - TURBO.EXE. В этом случае параметр помечен словами

"(только TURBO)". Два параметра применяются к IDE защищенного ре-

жима - BP.EXE. В этом случае параметр помечен словами (только

BP).

Параметр /C

Если вы используете параметр /C, за которым без пробела сле-

дует имя файла конфигурации, то IDE при запуске загружает этот

файл конфигурации. Например:

TURBO /Cmyconfig

О файлах конфигурации рассказывается ниже.

Параметр /D

Если вы укажете параметр /D, IDE сможет одновременно рабо-

тать с двумя мониторами. IDE проверяет, имеется ли на вашем

компьютере соответствующее оборудование, например, монохромная и

цветная плата. Если это не так, то IDE игнорирует данный пара-

метр. Режим с двумя мониторами полезно использовать при отладке

программы. Один монитор вы можете использовать как экран выводи-

мых программой данных, а другой - для работы с отладчиком. Ис-

пользуя два монитора, вы можете также выйти в командный процессор

DOS (FileіShell to DOS), так что на одном экране будет выводиться

IDE, а другой дает вам доступ к командной строке DOS.

Если система имеет два монитора, DOS интерпретирует один мо-

нитор как активный монитор. Для переключения между двумя монито-

рами можно использовать команду DOS MODE. Например, MODE CJ80 ак-

тивизирует цветной монитор, а MODE MONO активизирует монохромный

монитор. В режиме с двумя мониторами обычный экран IDE выводится

на неактивном мониторе, а вывод программы поступает на активный

монитор.

Поэтому когда вы на одном мониторе набираете в ответ на

подсказку DOS BP /D или TURBO /D, IDE выводится на другом монито-

ре. Когда вы хотите проверить программу на конкретном мониторе,

выйдите из IDE, переключите активный монитор на тот, на котором

вы хотите ее проверить, а затем снова дайте команду BP /D или

TURBO /D. Вывод программы затем будет поступать на тот монитор,

где вы набрали команду.

При использовании команды /D следует иметь в виду следующее:

* Не изменяйте активный монитор (используя, например, коман-

ду DOS MODE), когда вы находитесь в командном процессоре

DOS (FileіDOS Shell).

* Пользовательские программы, использующие прямой доступ к

портам видеоплаты неактивного монитора, не поддерживаются

и могут дать непредсказуемые результаты.

* Когда вы выполняете или отлаживаете программы, которые яв-

ным образом используют два монитора, не указывайте пара-

метр /D.

Параметр /E (только TURBO)

Используйте параметр /E для изменения размера динамически

распределяемой области памяти редактора. По умолчанию ее размер

равен 28К (минимальная установка). Максимальное значение - 128К.

Размер динамически распределяемой области памяти, превышающий

28К, улучшает производительность IDE только в том случае, если вы

используете в качестве устройства свопинга медленный диск. Если у

вас есть память EMS или вы разместили файл свопинга на виртуаль-

ном диске (см. параметр /S), не изменяйте используемый по умолча-

нию параметр.

Параметр /F (только BP)

С помощью параметра /F вы можете задать файл свопинга для

администратора Borland Pascal этапа выполнения (RTM.EXE). Напри-

мер, если вы компилируете прикладную программу, которая требует 4

мегабайта памяти, но на вашем компьютере доступно только два ме-

габайта, то вы можете задать файл свопинга 4-мегабайтной вирту-

альной памяти; ваша прикладная программа получит необходимую ей

для компиляции память. Для файла свопинга допустимы размеры от

1024К до 16384К. В следующем примере задается файл свопинга в 2

мегабайта:

BP /F2048

Когда вам больше не нужен будет файл свопинга виртуальной

памяти, выключите это параметр, задав файл нулевого размера:

BP /F0

Параметр /G

Используйте параметр /G для разрешения полного сохранения

графической памяти, при отладке графических программ в системах с

EGA, VGA или MCGA. При включении сохранения графического экрана

(Graphics Screen Save) IDE резервирует дополнительные 8 килобайт

для буфера, который размещается в EMS (при ее доступности).

Параметр /L

Используйте параметр /L, если вы работаете с IDE на жидкок-

ристаллическом или плазменном экране.

Параметр /N

Используйте параметр /N для разрешения или запрета проверки

на помехи на адаптере CGA. Если вы работаете с адаптером CGA, ко-

торый не дает на экране помехи ("снег") при обновлении изображе-

ния, запретите данный параметр. Если вы не работаете с CGA, этот

параметр не действует.

Параметр /O (только TURBO)

Используйте параметр /O для изменения размера оверлейной ди-

намически распределяемой памяти IDE. По умолчанию назначается

размер 90К. Если у вас есть EMS, то вы можете уменьшить размер

оверлейной динамически распределяемой памяти, не ухудшая произво-

дительности IDE и освободив дополнительную памяти для компиляции

и отладки программ.

Параметр /P

Используйте параметр /P, управляющий переключением палитр на

видеоадаптере EGA, когда ваша программа модифицирует регистры па-

литры. Палитра EGA будет восстанавливаться при каждом переключе-

нии экрана.

В общем случае вам не нужно использовать данный параметр,

пока ваша программа не модифицирует регистры палитры EGA или не

использует для переключения палитры BGI.

Параметр /R

Если параметр /R включен при запуске IDE, то текущим стано-

вится тот каталог, в котором вы находились во время последнего

выхода из IDE. По умолчанию этот параметр включен. Чтобы этот па-

раметр начал действовать, нужно также выбрать параметр IDE

OptionsіEnviromentіPreferences и установить параметр Desktop Auto

Save. Если вы не хотите, чтобы IDE запоминала последний каталог,

выключите параметр /R.

Параметр /S

Если ваша система не имеет дополнительной памяти, используй-

те параметр /S для задания диска и маршрута доступа к "быстрой"

области свопинга, такой как виртуальный диск (например, /Sd:\,

где d - дисковод). Если каталог свопинга не задан, то файл сво-

пинга создается в текущем каталоге.

Параметр /T

Если вы не хотите, чтобы IDE загружала библиотеку исполняю-

щей системы, запретите параметр /T. Для TURBO.EXE библиотекой ис-

полняющей системы является TURBO.TPL. В зависимости от целевой

платформы для BP.EXE библиотекой исполняющей системы может быть

TURBO.TPL (реальный режим), TPW.TPL (Windows) или TPP.TPL (защи-

щенный режим). Если библиотека исполняющей системы не загружена,

перед компиляцией или отладкой программ вам потребуется модуль

System. Запретив параметр /N и выделив SYSTEM.TPU из библиотеки

исполняющей системы с помощью TPUMOVER, вы можете увеличить ем-

кость IDE реального режима. Если вы используете IDE защищенного

режима, то может сделать тоже самое, выделив в зависимости от це-

левой платформы модуль SYSTEM.TPU, SYSTEM.TPW или SYSTEM.TPP. О

выборе целевой платформы рассказывается ниже.

Примечание: Об утилите TPUMOVER рассказывается в Главе

1 "Перемещение модулей" в "Руководстве по инструментальным

средствам и утилитам".

Параметр /W (только TURBO)

Используйте параметр /W, если вы хотите изменить размер ди-

намической памяти окна. По умолчанию этот размер устанавливается

в 32К. Минимальная установка - 24К; максимальная - 64К. Если вам

не требуется открывать в оперативной памяти много окон, уменьшите

размер динамической памяти окна. Размер по умолчанию дает IDE хо-

рошую емкость и достаточное оконное пространство.

Параметр /X (только TURBO)

Используйте параметр /X, если вы хотите, чтобы IDE использо-

вала дополнительную память (EMS). По умолчанию этот параметр

включен. При разрешении данного параметра IDE улучшает производи-

тельностье, размещая в дополнительной памяти перекрываемый код,

данные редактора и другие системные ресурсы.

Параметр /Y (только BP)

С помощью этого параметра вы можете сделать так, чтобы ком-

пилятор "запоминал" информацию об идентификаторах между компиля-

циями. Если данный параметр включен, и вы изменили свою програм-

му, но следующая компиляция завершается неудачно, то вам все рав-

но будет доступна информация об идентификаторах с предыдущей ком-

пиляции. Таким образом, вы сможете просмотреть свою программу и

определить, в чем состоит проблема. По умолчанию данный параметр

включен.

Установка параметров запуска в интегрированной среде

Параметры запуска вы можете также установить в самой интег-

рированной среде:

1. Выберите команду OptionsіEnviromentіStartup для вывода

диалогового окна Startup Options.

2. Выберите нужные параметры и задействуйте кнопку OK.

Установленные параметры будут действовать при следующем за-

пуске IDE.

Выход из IDE

Из IDE можно выйти двумя способами:

* Чтобы полностью выйти из IDE, выберите команду FileіExit.

Если вы внесли изменения, которые не были сохранены, IDE

выводит запрос, хотите ли вы сохранить перед выходом свои

программы.

* Чтобы временно выйти из IDE для ввода команд в ответ на

подсказку DOS, выберите команду FileіDOS Shell. IDE оста-

ется в памяти, но управление передается в DOS. Вы можете

ввести команды DOS и даже запустить другие программы. Ког-

да вы будете готовы вернуться в IDE, наберите в командной

строке EXIT и нажмите Enter. IDE выводится в том виде, как

вы из нее выше.

Использование справочной системы Help

Справочная система Help предоставляет вам возможность легко-

го доступа к детальной информации о языке Borland Pascal, интег-

рированной интерактивной среде, библиотеке исполняющей системе,

директивах компилятора и т.д.

Если вы ранее не работали со справочной системой Help для

DOS по языкам Borland, то, прочитав следующие разделы, вы можете

вывести справочный экран. Экран содержимого справочника Borland

Pascal Help Contents выводится при выборе команды HelpіContents.

Перемещение в справочной системе

Если вы посмотрите на справочный экран, то увидите текст,

который выводится цветом, отличным от окружающего текста. Это

ссылки. Вы можете использовать ссылки для вывода нового справоч-

ного экрана, содержащего новую информацию по соответствующей те-

ме. Выберите один из следующих методов:

* Дважды щелкните на ссылке "мышью".

* Если справочный экран не содержит командных кнопок:

Нажимайте повторно клавишу Tab, пока не будет подсвечена

ссылка, затем нажмите клавишу Enter.

* Если справочный экран представляет собой диалоговое окно с

командными кнопками:

- Если вы используете "мышь", щелкните "мышью" на кнопке

перекрестных ссылок Cross-ref.

- Если вы используете клавиатуру, нажмите Enter; при этом

по умолчанию выбирается кнопка Cross-ref. Чтобы выбрать

другую кнопку, нажимайте повторно клавишу Tab, пока не

будет подсвечена нужная кнопка, затем нажмите клавишу

Enter.

Выводится новый справочный экран Help с информацией по выб-

ранной теме. Вы перешли в новое место справочной системы. На этом

экране вы можете видеть другие ссылки, которые можно выбирать для

получения дальнейшей информации.

Чтобы вернуться к предыдущему экрану Help, выберите команду

HelpіPrevious Topic или нажмите клавиши Alt+F1.

Запрос помощи

Доступ к справочнику Help можно получить несколькими спосо-

бами:

* Выбрав команду Help в строке меню или нажав Alt+H для вы-

вода меню Help.

В меню Help вы можете выбрать вывод экрана оглавления

Contents, экрана тематического указателя Index по всей

справочной системе, детальную информацию по теме, на кото-

рую указывает курсор в окне редактирования или справку по

работе со справочной системой Help.

* Для вывода экрана тематического указателя Borland Pascal

Help Index нажмите клавиши Shift+F1.

Экран тематического указателя Index аналогичен тематичес-

кому указателю книги. Однако, вместо того, чтобы перевер-

нуть страницы для получения информации по нужной теме

здесь нужно дважды щелкнуть на ней кнопкой "мыши" или пе-

рейти к теме с помощью клавиши Tab и нажать Enter.

* Нажав клавишу F1.

Вы получите контекстно-зависимую информацию, зависящую от

того, что вы делаете в этот момент - редактируете, отлажи-

ваете программу, выбираете параметры меню и т.д.

Если вы находились в диалоговом окне, то увидите справоч-

ный экран по тому параметру, который выделен в момент на-

жатия F1.

* Выбрав командную кнопку Help в диалоговом окне.

При выборе командной кнопки Help вы получите информацию о

диалоговом окне.

* Поместив курсор на термин в окне редактирования и выбрав

Topic Search. Используйте любой из следующих методов:

- нажмите клавиши Ctrl+F1;

- выберите команду HelpіTopic Search;

- удерживая клавишу Ctrl, щелкните правой кнопкой "мыши"

(комбинация нажатий Ctrl+правая кнопка "мыши" должна

быть предварительно настроена - выберите команду

OptionsіEnviromentіMouse и выберите команду Topic

Search).

- выберите команду Topic Search в локальном меню окна ре-

дактирования (нажмите клавиши Alt+F10 для вывода на эк-

ран локального меню или щелкните правой кнопкой "мыши".

Примечание: О локальном меню окна редактирования расс-

казывается ниже.

В справочном экране выводится информация о термине, на кото-

ром установлен курсор в активном окне.

Копирование примеров исходного кода

Справочная система Help содержит примеры кода для каждой

процедуры и функции. Вы можете скопировать эти примеры из спра-

вочной системы в окно редактирования. Выполните следующие шаги:

1. Выведите справочный экран по интересующей вас процедуре

или функции.

2. Прокрутите справочное окно, пока не увидите в нем пример

исходного кода.

3. Для вывода локального меню Help нажмите клавиши Alt+F10

или щелкните правой кнопкой "мыши".

4. Скопируйте пример:

* для копирования всего примера выберите команду Copy

Example;

* для копирования части исходного кода подсветите то, что

вы хотите скопировать, и выберите команду Copy.

5. Вернитесь в окно редактирования и выберите команду

EditіPaste, нажмите клавишу Shift+Ins или выберите коман-

ду Paste в локальном меню окна редактирования.

Загрузка других справочных файлов

Интегрированная среда позволяет вам подключать к справочной

системе Help другие справочные файлы. Например, если вы хотите

получать справочную информацию по Turbo Vision, то можете загру-

зить справочный файл Turbo Vision. IDE объединяет тематические

указатели справочных файлов, что позволяет вам получить доступ в

экране Index как к обычной справочной системе Help, так и к спра-

вочной системе Turbo Vision.

Чтобы загрузить новую справочную систему Help, выполните

следующие шаги:

1. Выберите команду HelpіFiles (СправочникіФайлы).

Выводится диалоговое окно установки справочных файлов

Install Help Files.

2. Выберите команду New (Новый).

Выводится диалоговое окно Help Files (Справочные файлы).

Все справочные файлы в вашем каталоге BIN с расширением

.TPH выводится в блоке списка. Если вы не видите справоч-

ных файлов, измените каталог BP\BIN.

3. Дважды щелкните "мышью" на справочном файле, который вы

хотите включить в справочную систему, или выделите его и

нажмите клавишу Enter.

Примечание: Если вы хотите также выбрать второй

справочный файл, повторите этот шаг.

Диалоговое окно Install Help Files появляется вновь, и в

нем выводится справочный файл, который вы выбрали в блоке

списка.

4. Выберите командную кнопку OK.

5. Выберите команду HelpіIndex или нажмите клавиши Shift+F1.

В строке состояния вы можете увидеть краткое сообщение,

показывающее индексирование и слияние. После завершения

слияния вы можете прокрутить справочный экран и увидеть,

что вам доступны все темы в выбранных справочных файлах.

Тематические указатели остаются объединенными в течении

текущего сеанса. Если в диалоговом окне Preferences

(OptionsіEnviromentіPreferences) вы установили параметр

Enviroment Auto Save, то тематические указатели будут ос-

таваться объединенными и в следующих сеансах. Если вы не

сохранили свою операционную среду, то при следующем за-

пуске IDE тематический указатель Help возвращается в ис-

ходное состояние. Другими словами, объединение тематичес-

ких указателей не будет сохраняться от одного сеанса к

другому.

Примечание: О сохранении операционной среды расска-

зывается ниже.

Если вы не хотите видеть на экране тематического указателя

Index конкретные записи Help, то можете "удалить" справочный

файл:

1. Выберите команду HelpіFiles.

2. Выберите имя справочного файла, который вы больше не хо-

тите просматривать.

3. Выберите команду Delete.

4. Выберите командную кнопку OK.

Выход из справочника Help

Чтобы закрыть окно Help и вернуться в свою прикладную прог-

рамму вы можете выбрать один из следующих методов:

* Нажать клавишу Esc.

* Щелкнуть "мышью" на элементе закрытия окна Help.

* Щелкнуть "мышью" вне окна Help.

Если вы хотите вновь вывести предыдущий справочный экран,

нажмите клавиши Alt+F1.

Запись и редактирование исходного кода

Набирайте текст, как это делается в любом редакторе. Для за-

вершения строки нажимайте Enter. Когда вы введете достаточно

строк, чтобы заполнить экран, он будет прокручиваться.

Примечание: В IDE вы можете открыть столько окон,

сколько позволяет память вашей системы.

Полный список команд редактирования вы можете найти в Прило-

жении A ("Справочник по редактору") "Руководства программиста".

Настройка конфигурации редактора

Для модификации поведения редактора Borland Pascal имеется

несколько параметров. Для вывода диалогового окна Editor выберите

команду OptionsіEnviromentіEditor.

Чтобы подробнее узнать о каждом параметре, выделите данный

параметр и нажмите клавишу F1. Справочная система Help поясняет,

что делает данный параметр.

Примечание: О выделении синтаксиса в редакторе расска-

зывается ниже.

Изменение решения: команда Undo

Редактор имеет команду отмены Undo, которая облегчает изме-

нение вашего решения при выполнении каких-либо действий и исправ-

ление ошибки. Чтобы отменить действие предыдущей операции редак-

тирования, выберите команду EditіUndo или нажмите клавиши

Alt+Backspace. Если вы продолжаете выбирать команду Undo, редак-

тор продолжает отменять действия. С помощью команды возобновления

EditіRedo вы можете также отменить саму команду Undo.

Команда Undo вставляет все удаленные вами символы, удаляет

любой вставленный символ, заменяет все перезаписанные символы и

перемещает курсор обратно на предыдущую позицию. Если вы отменяе-

те блочную операцию, то файлы выводится в том виде, какой он имел

перед выполнение блочной операции.

Команда Undo не изменяет установку параметров, влияющих бо-

лее чем на одно окно. Например, если вы используете клавишу Ins

для изменения режима вставки на режим замены, а затем выберите

Undo, редактор не изменит режим обратно не режим вставки. Но если

вы удалили символ, перешли в режим замены, затем выбрали команду

Undo, то удаленные ранее символ выводится вновь.

Групповая отмена

Параметр Group Undo в диалоговом окне OptionsіEnviromentі

Editor влияет на то, как ведет себя команда Undo и соответствую-

щая команда Redo. Если вы выберите параметр Group Undo (Групповая

отмена), при нажатии клавиш Alt+Backspace или EditіUndo, редактор

изменяет последнюю группу команд.

Приведем пример того, как работает групповой параметр. Если

вы наберете, например, MISTAKE и параметр Group Undo установлен,

то Undo удаляет все слово. Если параметр Group Undo не выбран, и

вы набираете MISTAKE, Undo удаляет только последний символ, букву

E. Чтобы отменить слово MISTAKE при выключенном параметре Group

Undo, вам нужно использовать команду Undo семь раз.

Примечание: Группа - это последовательность команд од-

ного типа.

Вставки, удаления, замены и перемещения курсора являются

групповыми операциями. Когда вы меняете тип команды, старая груп-

па завершается и начинается новая. Для редактора вставка возврата

каретки нажатием клавиши Enter - это вставка, за которой следует

перемещение курсора. Поскольку тип редактирования изменился (вы

вставили символы, затем переместили курсор), группа вставки сим-

волов завершается, когда вы нажимаете Enter.

Отмена отмены

Команда EditіRedo изменяет на обратное действие последней

команды Undo. Redo немедленно действует только после команды Undo

или другой команды Redo. Последовательность команд Redo отменяет

действие последовательности команд Undo. Как и в случае команды

Undo, на команду Redo влияет параметр Group Undo.

Работа с блоками текста

Блок текста - это любой объем текста (от одного символа до

сотен строк), который выделен на экране. В каждый момент времени

в окне может быть выделен только один блок.

Выделение блока

Для выделения блока текста существует по крайней мере три

способа:

* Буксируйте "мышь" по тексту, который вы хотите выделить.

* Переместите свой курсор в начало блока текста, нажмите

клавишу Shift и, удерживая ее, переместите курсор к концу

блока с помощью клавиш стрелок.

* Щелкните "мышью" в начале блока, переместите курсор к кон-

цу блока с помощью клавиш стрелок, затем, нажав Shift,

снова щелкните кнопкой "мыши".

Если вы уже работали с редакторами Borland ранее, то можете

использовать команды работы с блоками как обычно. Таблицу команд

редактора Borland для работы с блоками можно найти в Приложении A

("Справочник по редактору") "Руководства программиста".

Вырезание, копирование и вставка блоков

После выбора блока его можно скопировать, переместить или

записать в файл.

* Чтобы вырезать выделенный текст, нажмите клавиши Shift+Del

или выберите команды EditіCut. Выделенный блок удаляется

из текста и помещается в буфер вырезанного изображения

("карман") - временную область памяти.

* Для копирования выделенного текста нажмите клавиши

Ctrl+Ins или выберите команду EditіCopy. Выделенный блок

остается в тексте, а его копия помещается в буфер вырезан-

ного изображения и готова для вставки в другом окне реда-

ктирования.

* Чтобы вставить (скопировать) текст, содержащийся в буфере

вырезанного изображения, в активное окно, нажмите клавиши

Shift+Ins или выберите команду EditіPaste. Блок, содержа-

щийся в буфере, вставляется в текущей позиции курсора.

* Для стирания (удаления) выделенного текста нажмите клавиши

Ctrl+Del или выберите команду EditіClear. Выделенный блок

удаляется из текста, и копия не помещается в буфер выре-

занного изображения. Единственный способ восстановления

удаленного текста состоит в применении команды EditіUndo.

Изменение поведения выделенных блоков

На поведение в редакторе выделенных блоков влияют два пара-

метра - Persistent Blocks и Overwrite Blocks. Их можно найти в

диалоговом окне OptionsіEnviromentіEditor.

* Если включен параметр Persistent Blocks (Постоянные бло-

ки), то выделенные блоки остаются выделенными пока вы их

не удалите или не отмените выделение (или пока не выделите

другой блок).

* Если параметр Persistent Blocks выключен, и вы перемещаете

курсор за выделенный блок, то выделение блока отменяется.

* Если параметр Persistent Blocks выключен, то параметр

Overwrite Blocks setting игнорируется.

* Если включен параметр Overwrite Block (Затирание блока), и

вы набираете букву, то выделенный блок заменяется набран-

ной буквой.

* Если параметр Overwrite Block выключен, и вы набираете

букву, то буква вставляется после выделенного текста.

* Если параметр Overwrite Block включен, а параметр

Persistent Block выключен, и вы нажимаете клавишу Del или

клавишу Backspace, то весь выделенный текста удаляется.

Если вы вставляете текст (нажимая символ или вставляя его из

буфера), то весь выделенный текст заменяется вставленным текстом.

Поиск

Вы можете использовать редактор для поиска строки в исходном

коде. Для поиска строки текста в активном окне редактирования вы-

полните следующие шаги:

1. Выберите команду SearchіFind. При этом открывается диало-

говое окно Find Text (Поиск текста).

2. Наберите искомую строку в блоке ввода Text to Find.

3. Вы можете также задать различные параметры поиска:

* Кнопки с независимой фиксацией Options (Параметры) оп-

ределяют, будет при поиске:

- различаться регистр символов;

- выполняться поиск только полного слова;

- использоваться регулярные выражения (об использовании

регулярных выражений в строках поиска рассказывается

в Приложении A "Справочного руководства программис-

та").

* Кнопки с зависимой фиксацией Scope (Область действия)

управляют тем, в какой части файла выполняется поиск -

во все файле или только в выделенном тексте.

* Кнопки с зависимой фиксацией Direction (Направление)

управляют тем, в каком направлении вы выполняете поиск

- в прямом или в обратном.

* Кнопки с зависимой фиксацией Origin (Начало) управляет

тем, откуда начинается поиск.

4. Для выполнения поиска выберите командную кнопку OK.

5. Если вы хотите выполнить повторный поиск того же элемен-

та, выберите команду SearchіSearch Again (ПоискіПовторный

поиск).

По умолчанию в блоке ввода Text to Find (Искомый текст) вы-

водится слово, на котором позиционируется курсор. Если вы не хо-

тите, чтобы это происходило, сделайте следующее:

1. Выберите команду OptionsіEnviromentіEditor.

2. Отмените установку параметра Find Text at Cursor.

При выводе диалогового окна Find в блоке ввода выводится

слово, на котором находится курсор. Если вы хотите вместо отдель-

ного слова найти предложение или группу слов, нажмите клавишу >

(когда курсор находится в блоке ввода Find Text). В блоке ввода

появляется дополнительный текст, как если бы он "вытягивался" из

окна редактирования.

Поиск и замена

Для поиска строки текста и замены ее другой строкой выберите

команду SearchіReplace (ПоискіЗамена). Выберите в диалоговом окне

параметры, как это делается для команды Search, но включите в

блок Next Text строку замены.

Если вы хотите заменить все вхождения строки в своем файле,

выберите параметр Change All. Если вы выберете параметр Prompt on

Replace, редактор будет выполнять поиск, пока не найдет указанную

строку, затем запросит, хотите ли вы ее заменить. Если вы не ис-

пользуете параметр Prompt on Replace, лучше выбрать параметр

Whole Words Only (Только полные слова). Это позволит избежать

случаев замены символов в середине слова - возможно, вы не хоти-

те, чтобы это происходило.

Соответствие пар ограничителей

Иногда вам не требуется искать текст, а нужно найти соот-

ветствующий парный ограничитель (фигурную или квадратную скобку,

одинарную кавычку, двойную кавычку, двойной знак вопроса или ком-

бинацию скобки и звездочки, обозначающую комментарий). Предполо-

жим у вас есть сложное выражение с множеством вложенных выраже-

ний, и вы хотите убедиться, что не пропущена ни одна скобка. Нуж-

но сделать следующее:

1. Поместите курсор на ограничителе (скобке).

2. Нажмите клавиши Ctrl+Q[.

Редактор немедленно перемещает курсор к ограничителю, соот-

ветствующему выбранному. Если он перемещается на ограничитель,

отличный от ожидаемого вами, то это указывает на ошибку.

Если для выбранного вами ограничителя нет соответствующего

парного, редактор не смещает курсор.

На самом деле есть две команды редактирования пар ограничи-

телей: одна для поиска соответствующей пары в прямом направлении

(Ctrl+Q[), а другая - в обратном (Ctrl+Q]).

Если вы поместите курсор на одинарную или двойную кавычку,

редактор не знает, в каком направлении нужно искать парный огра-

ничитель. В этом случае вы должны задать корректную команду поис-

ка пары.

Для круглых, квадратных и фигурных скобок не имеет значения,

какая команда используется для поиска пары. Редактор знает, в ка-

ком направлении искать соответствующий ограничитель.

Приведем пример, иллюстрирующий соответствие пар:

совпадающая совпадающая совпадающая

пара пара пара

ЪБї ЪДДБДДї ЪДДБДДї

Array1[Array2[x]] ((x > 0) and (y < 0)

АДДДДВДДДДЩ АДДДДДДДДДВДДДДДДДДЩ

совпадающая совпадающая

пара пара

Рис. 4.1 Поиск соответствующей квадратной или круглой скоб-

ки.

Переход к строке с заданным номером

Редактор отслеживает, на какой строке находится курсор в

строке состояния окна. Быстрый способ перехода в определенное

место в файле состоит в использовании команды Go to Line Number

(Переход на строку с номером):

1. Выберите команду SearchіGo to Line Number.

2. Наберите номер строки, на которую вы хотите перейти.

3. Выберите командную кнопку OK.

Использование локального меню окна редактирования

Многие из функций, выполняемых вами при работе в окне редак-

тирования, удобно расположены в локальном меню окна редактирова-

ния. Когда окно редактирования активно, вы можете вывести локаль-

ное меню двумя способами:

* Нажать клавиши Alt+F10.

* Щелкнуть правой кнопкой "мыши".

Интегрированная среда IDE содержит также другие локальные

меню. Прочитав об использовании справочника Help, отладке и прос-

мотре, вы узнаете, где находятся остальные локальные меню.

Выделение синтаксиса

Когда вы пишете или редактируете программу на Паскале, неко-

торые части исходного кода выводятся на экран разными цветами.

Например, зарезервированные слова Borland Pascal выводятся белым

цветом, а остальной текст - желтым. Такое цветовое выделение ис-

ходного кода облегчает быструю идентификацию частей кода.

Цвета текста

Чтобы изменить цвет элемента, выполните следующие шаги:

1. Выберите команду OptionsіEnviromentіColors. Выводится ди-

алоговое окно Colors (Цвета).

ЙН[ ]НННННННННННННННННННННННColorsННННННННННННННННННННННННН»

є є

є Group Item є

є Compiler ^ Whitespace ^ ЪДForegroundДДДДДї є

є Desktop ± Comments ± і±±±±ІІІІ±±±± і є

є Dialogs ± Reserved words ± іІІІІЫЫЫЫ °°°°і є

є Help ± Identifiers ± іЫЫЫЫ °°°°ЫЫЫЫі є

є Menus ± Symbols ± АДДДДДДДДДДДДДДДДЩ є

є Messages ± Strings ± ЪДBackgroundДДДДДї є

є Output ± Members ± і±±±±ІІІІ±±±± і є

є Register Ы Assembler ± іІІІІЫЫЫЫ °°°°і є

є ІSyntaxІІІІІІІ± ± іЫЫЫЫ °°°° і є

є Watches ± ± АДДДДДДДДДДДДДДДДЩ є

є ± Ы Text°Text°Text° є

є v v Text°Text°Text° є

є є

є ЫЫЫЫЫOKЫЫЫЫ ЫЫЫCancelЫЫЫ ЫЫЫHelpЫЫЫЫ є

є ±±±±±±±±±±± ±±±±±±±±±±±± ±±±±±±±±±±± є

є є

ИННННННННННННННННННННННННННННННННННННННННННННННННННННННННННј

Рис. 4.2 Диалоговое окно Colors.

Colors - цвета; Group - группа; Compiler - компилятор;

Desktop - оперативная область; Dialogs - диалоги; Help -

справочник; Menus - меню; Messages - сообщения; Output -

вывод; Register - регистр; Syntax - синтаксис; Watches -

выражения просмотра; Item - элемент; Whitespace - пробел;

Comments - комментарий; Reserved words - зарезервирован-

ные слова; Identifiers - идентификаторы; Symbols - имена;

Strings - строки; Members - элементы (члены); Assembler -

ассемблер; Foreground - основной цвет; Background - фоно-

вый цвет.

В блоке списка слева выводятся все группы элементов, ко-

торые вы можете выделять цветом в IDE.

2. Прокрутите блок списка Group, пока не увидите группу

Syntax (Синтаксис). Выберите группу Syntax и в блоке

списка Item выведутся элементы кода Паскаля, которые вы

можете выделять цветом.

3. Выделите элемент, который вы хотите изменять в блоке

списка Item.

4. Выберите основной и фоновый цвет, который вы хотите наз-

начить для элемента.

* Чтобы выбрать фоновый цвет с помощью "мыши", щелкните

ее кнопкой на нужном цвете матрицы цветов Foreground.

Чтобы выбрать цвет с помощью клавиатуры, нажимайте кла-

вишу Tab, пока не будет выбрана матрица фонового цвета,

затем для выделения цвета используйте клавиши стрелок.

* Чтобы выбрать фоновый цвет, выберите нужный цвет в мат-

рице цветов Background.

Как только вы сделаете выбор цвета, он будет отражен в

примере текстового окна.

5. Выберите командную кнопку OK.

Выбор файлов для выделения

По умолчанию выделение синтаксиса происходит только в файлах

с расширениями .PAS и .INC. Вы можете использовать выделение син-

таксиса в файлах другого типа.

Чтобы изменить тип файлов, выводимых с выделением синтакси-

са, сделайте следующее:

1. Выберите команду OptionsіEnviromentіEditor.

2. Измените текст в блоке Highlight Extensions.

Допускается любое разрешенное имя файла DOS, включая тра-

фаретные символы. Вы можете задать несколько имен файлов.

В этом случае их нужно разделить двоеточиями.

Запрещение выделения синтаксиса

Если вы не хотите использовать выделение синтаксиса, то мо-

жете выключить его:

1. Выберите команду OptionsіEnviromentіEditor.

2. Отмените выбор параметра Syntax Highlight (Выделение син-

таксиса).

Цвет обычного текста изменяется модификацией параметра

EditorіNormal Text в диалоговом окне OptionsіEnviromentіCoplors.

Если вы не выключите подсветку синтаксиса, изменение цвета обыч-

ного текста не действует.

Печать исходного кода

Если вы хотите получить печатную копию своего исходного ко-

да, выберите команду FileіPrint. IDE расширяет символы табуляции

(заменяя табуляцию соответствующим числом пробелов и затем печа-

тает ваш файл.

Выделение элементов синтаксиса при печати

Вы можете напечатать текст таким образом, чтобы синтаксичес-

кие элементы были выделены. Перед печатью вы должны пропустить

выводимый на принтер текст черед программу-фильтр PRNFLTR.EXE:

1. Выберите команду FileіPrinter Setup.

2. Если программа PRNFLTR.EXE не находится по вашему маршру-

ту или в текущем каталоге, добавьте информацию о текущем

маршруте в запись PRNFLTR в диалоговом окне Filter Path.

3. В блоке ввода Command Line вы можете указать принтер

Epsor, HP LaserJet или PostScript.

* Если вы используете принтер Epson, введите:

$NOSWAP /EPSON

* Если вы используете принтер HP LaserJet, введите:

$NOSWAP /HP

* Если вы используете принтер PostScript, введите:

$NOSWAP /PS

Если у вас другой тип принтера, то вы можете модифициро-

вать файл PRNFLTR.PAS, чтобы воспринимались соответству-

ющие коды.

4. Установите параметр Send Highllighting Escape Codes.

5. Выберите командную кнопку OK.

6. Выберите команду FileіPrint.

Если параметр Syntax Highlight установлен, ваш текст пе-

чатается с выделением синтаксических элементов.

Работа с файлами

При программировании в IDE вы можете создавать новые файлы,

открывать существующие файлы и сохранять их. Основные команды ра-

боты с файлами перечислены в следующей таблице:

ЪДДДДДДДДДДДДДДДДДДВДДДДДДДДДї

і Команда і Описание і

ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДґ

і FileіNew і Открывает новое окно редактиро-і

і і вания и присваивает ему временноеі

і і имя. і

ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДґ

і FileіOpen і Выводит диалоговое окно, с по-і

і і мощью которого можно открытьі

і і файл. і

ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДґ

і FileіSave і Сохраняет файл в активном окнеі

і і редактора на диске. і

ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДґ

і FileіSave As і Сохраняет файл в активном окнеі

і і редактора под другим именем. і

ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДґ

і FileіSave All і Сохраняет все модифицированныеі

і і файлы. і

АДДДДДДДДДДДДДДДДДДБДДДДДДДДДЩ

Открытие файлов

Для открытия файла выполните следующие шаги:

1. Выберите команду FileіOpen. Выводится диалоговое окно

Open a File (Открытие файла). Для задания открываемого

файла вы можете выполнить одно из следующих действий.

* В блоке ввода наберите полное имя файла.

* Наберите имя файла с трафаретными символами. Это от-

фильтровывает список файлов в соответствии с вашими

спецификациями. В списке Files выберите имя файла, ко-

торый вы хотите редактировать.

* Для вывода списка протокола (спецификаций имен файлов,

которые вы задавали ранее), нажмите стрелку вниз. Выбе-

рите требуемое имя файла или спецификацию. Выбор специ-

фикации файла выводит файлы, соответствующие данной

спецификации.

* Дважды щелкнув "мышью" на имени другого каталога в

списке файлов, просмотрите содержимое этого каталога.

Выберите имя файла, который вы хотите редактировать.

2. После того как имя файла, который вы хотите редактиро-

вать, будет выделено в блоке ввода, выберите команду Open

(Открыть) или Replace (Заменить). Команда Open загружает

файл в новое окно редактирования; команда Replace заменя-

ет содержимое активного окна редактирования выбранным

файлом.

После выделения имени файла вы можете просто нажать клавишу

Enter или, когда увидите имя нужного файла в списке, дважды щелк-

нуть на нем кнопкой "мыши". Файл будет открыт.

Если вы откроете один или более файлов, а затем закроете их,

то увидите их список в нижней части меню File (до пяти файлов).

Если вы выберите в меню один из этих пяти файлов, то файл откры-

вается в окне редактирования. Когда вы работаете с несколькими

открытыми файлами, то можете закрыть некоторые из них, при необ-

ходимости быстро открывая их снова с помощью списка. Это уменьшит

перегруженность вашей оперативной области.

Вы можете также изменить используемый по умолчанию каталог

на тот, в котором находится открываемый вами файл. Это изменяет

поведение, заданное переменными операционной среды Windows:

1. Выберите команду OptionsіEnviromentіPreferences.

2. Установите параметр Change Dir (Смена каталога).

3. Выберите командную кнопку OK.

Открытие файла в позиции курсора

IDE дает вам быстрый способ открытия файла, имя которого на-

ходится в вашем исходном коде. Вы найдете это удобным, когда пот-

ребуется просмотреть код модуля или включаемого файла, используе-

мого в вашей программе.

1. Поместите курсор на имя файла, который вы хотите открыть.

2. Нажмите клавиши Ctrl+Enter или выведите локальное меню

окна редактирования и выберите команду Open File at

Cursor (Открытие файла в позиции курсора).

Компиляция и выполнение

IDE предоставляет вам несколько способов создания выполняе-

мой программы, модуля или (если вы используете защищенный режим)

динамически компонуемую библиотеку. Вы можете:

* Скомпилировать текущий файл с помощью команды (Compileі

Compile).

* Скомпилировать все измененные файлы (CompileіMake).

* Скомпилировать все файлы проекта (CompileіBuild).

* Скомпилировать и выполнить программу (RunіRun).

Каждая из этих возможностей подходит для конкретной ситуа-

ции. Следующие разделы помогут вам решить, какую возможность луч-

ше использовать.

Выбор целевой платформы

Если вы используете BP.EXE, то перед компиляцией своей прог-

раммы вам нужно сообщить IDE, какой вид прикладной программы вы

создаете: программу DOS реального режима, программу Windows или

программу DOS защищенного режима. Тип создаваемой прикладной

программы называется целевой платформой.

Примечание: TURBO.EXE может создавать приложение ре-

ального режима.

Для выбора целевой платформы сделайте следующее:

1. Выберите команду CompileіTarget.

2. В диалоговом окне Target выберите нужную целевую платфор-

му.

3. Выберите командную кнопку OK.

При компиляции модуля расширения имени файла полученного в

результате модуля в зависимости от целевой платформы будут разли-

чаться:

ЪДДВДДДДДДї

і Целевая платформа і Расширение имени файла модуля і

і і объектного кода і

ГДДЕДДДДДДґ

і Реальный режим DOS і .TPU і

і і і

і Windows і .TPW і

і і і

і Защищенный режим DOS і .TPP і

АДДБДДДДДДЩ

Компиляция

Команда CompileіCompile компилирует только файл в активном

окне редактирования. При компиляции программы выводится окно сос-

тояния, в котором сообщается о ходе и результатах компиляции.

Когда компиляция и компоновка будет выполнена, нажмите любую кла-

вишу. Окно состояния исчезнет. Если имеется ошибка, в верхней

части окна редактирования вы увидите сообщение об ошибке, а кур-

сор будет позиционирован на ту строку кода, где имеется ошибка.

Выбор места назначения

Если вы используете IDE защищенного режима, то с помощью ко-

манды CompileіDestination можете выбрать компиляцию программы на

диск или в память. Если вы выберете компиляцию на диск, ваш вы-

полняемый код сохраняется на диске в виде файла .EXE. Компиляция

на диск увеличивает объем памяти, доступной в IDE для компиляции

и отладки вашей программ. При выборе компиляции в память ваша

программа будет записываться в память, и, если вы ее не сохрани-

те, будет потеряна при выходе из IDE.

При компиляции на диск полученные в результате файлы .EXE

или .TPU сохраняются в том же каталоге, что и исходные файлы, или

в каталоге EXE and TPU (OptionsіDirectories), если он задан.

Формирование (Make)

Если ваша программа включает в себя не только исходный код в

активном окне, например, основной файл, один или более модулей,

внешние модули на языке ассемблера и т.д., то вы можете сформиро-

вать свою программу. При формировании компилируется весь исходный

код, который был модифицирован с момента последней компиляции.

Команда CompileіMake создает файл .EXE или модуль. Если вы

в качестве целевой платформы используете IDE защищенного режима и

Windows, она может также создавать динамически компонуемую библи-

отеку (DLL).

Примечание: О создании DLL рассказывается в Главе 11

"Библиотеки динамической компоновки" "Руководства по язы-

ку".

Команда Make (Формирование) использует следующие правила:

* Если задан основной файл, то он компилируется. В противном

случае компилируется файл в активном окне редактирования.

Перед компиляцией IDE проверяет все файлы, чтобы убедить-

ся, что они существуют и являются текущими.

Примечание: Более подробно об основных файла расска-

зывается ниже.

* Если исходный файл для данного модуля модифицирован с мо-

мента создания файла .TPU, .TPW или .TPP (объектный код),

то этот модуль перекомпилируется.

* Если изменяется интерфейс для данного модуля, перекомпили-

руются все другие зависящие от него модули.

Примечание: О модулях подробнее рассказывается в Гла-

ве 7 "Модули Borland Pascal".

* Если модуль компонуется с файлом .OBJ (внешние подпрограм-

мы) и файл .OBJ является более новым, чем модули .TPU,

.TPW или .TPP, то модуль перекомпилируется.

* Если модуль содержит включаемый файл, и включаемый файл

более новый, чем модули .TPU, .TPW или .TPP, то модуль пе-

рекомпилируется.

Если компилятор не может найти исходный код модуля, то мо-

дуль не компилируется и используется как есть.

Построение (Build)

Команда CompileіBuild (КомпиляцияіПостроение) перестраивает

все компоненты вашей программы независимо от того, являются они

текущими или нет.

Эта команда аналогична команде CompileіMake, только она вы-

полняет полную перекомпиляцию, даже если файл не изменялся. Если

вы остановите команду Build, нажав клавиши Ctrl+Break, или полу-

чите ошибки, которые прекращают построение, то, выбрав Compileі

Make, вы можете определить, где это произошло.

Если в IDE реального режима DOS вы выбрали компиляцию в па-

мять, то все файлы .TPU обновляются на диске (для всех перекомпи-

лируемых командой Build модулей).

Выполнение

После создания выполняемого файла вы можете попробовать, как

она работает. Для этого можно использовать команду RunіRun. На

самом деле вам не нужно предварительно компилировать свою прог-

рамму. Если ваш код изменился с момента последней компиляции, ко-

манда Run автоматически формирует вашу программу и затем выполня-

ет ее.

Если ваша программа представляет собой прикладную программу

DOS защищенного режима, то в текущем каталоге или по маршруту DOS

у вас должны находиться файлы DPMI16BL.OVL и RTM.EXE, в противном

случае программа выполняться не будет. Вы можете свободно расп-

ространять эти файлы с готовой прикладной программой.

Передача программе параметров

При запуске программы вы можете передать ей параметры ко-

мандной строки. Для вывода диалогового окна Parameters (Парамет-

ры) и набора списка параметров, которые вы хотите использовать,

выберите команду RunіParamenters.

Параметры компилятора и компоновщика

IDE позволяет вам выбрать несколько параметров, влияющих на

характер компиляции кода. Для вывода диалогового окна параметров

компилятора Compiler Options выберите команду OptionsіCompiler.

Если вы не уверены относительно того, что делает конкретный пара-

метр, выберите его в диалоговом окне, в строке состояния появится

поясняющая справка. Для вывода более подробной информации о дан-

ном параметре нажмите клавишу F1 или выберите команду Help для

получения справочной информации обо всем диалоговом окне Compiler

Options.

ЙН[ ]ННННННННННННННННННННННCompiler OptionsННННННННННННННННННННН»

є Compiler settings for: ±±Real mode target±±±±±±±±±±v±є

єДДДДДДДДДДДДДє

є Code generation є

є ±[±]±Force±far±calls±±±±±±±±±[±]±286±instructions±±±±±±±±± є

є ±[±]±Overlays±allowed±±±±±±±±[±]±Smart±callbacks±±±±±±±±±± є

є ±[X]±Word±align±data±±±±±±±±±[±]±Windows±stack±frames±±±±± є

є Runtime errors Syntax Options є

є ±[±]±Range±checking±±±±± ±[X]±Strict±var-strings±±±±±±± є

є ±[X]±Stack±checking±±±±± ±[±]±Complete±boolean±eval±±±± є

є ±[X]±I/O±checking±±±±±±± ±[X]±Extended±syntax±±±±±±±±±± є

є ±[ ]±Overflow±checking±± ±[±]±Typed±@±operator±±±±±±±±± є

є Debugging ±[±]±Open±parameters±±±±±±±±±± є

є ±[X]±Debug±Information±± Numeric processing є

є ±[X]±Local±symbols±±±±±± ±[±]±8087/80287±±±±±±±±±±±±±±± є

є ±[X]±Symbol±information± ±[X]±Emulation±±±±±±±±±±±±±±±± є

є є

є Conditional defines є

є ЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫvЫ є

є є

є ЫЫЫЫЫOKЫЫЫЫ ЫЫЫCancelЫЫЫ ЫЫЫHelpЫЫЫЫ є

є ±±±±±±±±±±± ±±±±±±±±±±±± ±±±±±±±±±±± є

є є

ИНННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННј

Рис. 4.3 Диалоговое окно Compiler Options.

Compiler settings for - установки компилятора для; Real mode

target - целевая платформа реального режима; Code generation -

генерация кода; Force far calls - принудительное использование

вызовов дальнего типа; 286 instructions - инструкции процессора

286; Overlays allowed - допустимость оверлеев; Smart callbacks -

эффективные вызовы; Word align data - выравнивание данных на гра-

ницу слова; Windows stack frames кадры стека Windows; Runtime

errors - ошибки этапа выполнения; Syntax Options - синтаксические

ошибки; Range checking - проверка диапазона; Strict var-strings -

строгая проверка строковых переменных; Stack checking - проверка

стека; Complete boolean eval - полное вычисление булевских выра-

жений; I/O checking - проверка ввода-вывода; Extended syntax -

расширенный синтаксис; Overflow checking - проверка переполнения

стека; Typed @ operator - типизованная операция @; Debugging -

отладка; Open parameters - открытые параметры; Debug Information

- отладочная информация; Numeric processing - числовая обработка;

Local symbols - локальные идентификаторы; 8087/80287 - процессоры

8087/80287; Symbol information - локальная информация; Emulation

- эмуляция; Conditional defines - условные определения.

Задание параметров

компилятора для целевой платформы

Выбираемые вами параметры компилятора в сильной степени за-

висят от того, какую целевую платформу вы используете. Например,

если вы создаете приложение DOS реального режима, то можете раз-

решить использование оверлеев, что не требуется для программ

Windows или защищенного режима DOS.

Для указанной целевой платформы вы можете установить стан-

дартные параметры компилятора:

Примечание: Меню Compiler Options компилятора

TURBO.EXE не имеет параметра Compiler Setting For.

1. Для вывода прокручиваемого списка щелкните "мышью" на

стрелке v или нажмите клавишу стрелки вниз при выборе

блока списка Compiler Setting For.

2. Проверьте выбранную целевую платформу.

IDE автоматически устанавливает обычно используемые парамет-

ры. В любой момент вы можете переопределить эти выбранные в IDE

параметры.

Если параметр компилятора несовместим с выбранной целевой

платформой, то он становится тусклым, и вы не можете его выби-

рать.

Установка параметров

компилятора для всех целевых платформ

Если вы хотите чтобы конкретный параметр компилятора был ус-

тановлен независимо от используемой целевой платформы, сделайте

следующее:

1. В качестве значения параметра Compiler Settings For выбе-

рите All Targets.

2. Установите или отмените параметр компилятора, который вы

хотите установить.

Например, если вы хотите использовать инструкции процессора

286 для всех платформ, выберите All Targets (Все платформы), за-

тем установите параметр 286 instructions.

Когда вы выбираете All Targets, то можете увидеть, что в не-

которых кнопках с независимой фиксацией выводится вопросительный

знак (?). Это указывает, то установка параметра для всех платформ

не является одинаковой. Вы можете изменить этот параметр, сделав

его одинаковым для всех платформ, или оставить как есть.

Задание параметров компоновщика

Характер компоновки вашего кода зависит от установок в диа-

логовом окне Linker Options (Параметры компоновщика). Для его вы-

вода выберите команду OptionsіLinker. Если нужна более детальная

информация, выберите Help.

Включение в код директив компилятора

Существует еще один способ задания режима компиляции исход-

ного кода. Вместо использования для установки параметров диалого-

вых окон вы можете включить в свой код директивы компилятора.

Например, вы можете включить в свою программу проверку диапазона,

установив в диалоговом окне OptionsіCompiler параметр Range

Checking, или поместить в исходный код директиву {$R+}. Полное

описание директив компилятора и их использования вы можете найти

в Главе 2 ("Директивы компилятора") "Справочного руководства

программиста".

Включаемые в исходный код директивы компилятора имеют боль-

ший приоритет, чем параметры компилятора, устанавливаемые в IDE.

Например, если в IDE вы установите параметр Range Checking, но

ваша программа включает в себя директиву {R-}, то программа ком-

пилируется с выключенной проверкой диапазона.

Оптимизация кода

Некоторые параметры компилятора, поскольку они включают в

программу код проверки и обработки ошибок, влияют как на размер,

так и на скорость вашего кода. Хотя такие параметры полезно ис-

пользовать при разработке программы, без них вы можете получить

более быстрый и компактный код.

Приведем параметры, влияющие на оптимизацию кода. Каждая ди-

ректива компилятора сопровождается указанием соответствующего па-

раметра компилятора. Рассмотрим использование для завершающей

компиляции следующих параметров:

* Выравнивание данных на границу слова Word Align Data

({$A+}) выравнивает переменные и типизированные константы

на границу слова, что дает в системах с процессорами 80x86

более быстрый доступ к памяти.

* Выключение полного вычисления булевских выражений Complete

Boolean Evaluation ({$B-}) дает код, который в зависимости

от установки ваших булевских выражений более быстро рабо-

тает.

* При выключенной эмуляции Emulation ({$E-}) компилятор не

будет выполнять компоновку с библиотекой исполняющей сис-

темы, эмулирующей сопроцессор 80x87. Она должна использо-

вать сопроцессор 80х87 (в случае его наличия) или стан-

дартный 6-байтовый тип Real. При компиляции приложений

Windows эмуляция не используется; при наличии директивы

эмуляции компилятор ее игнорирует.

* Когда задана генерация кода процессора 80286 Code

Generation ({$G+}), компилятор для улучшения генерации ко-

да использует дополнительные инструкции процессора 80286.

Скомпилированные таким образом программы не будут работать

на процессорах 8088 и 8086.

* При выключенной проверке ввода-вывода I/O Checking ({$I-})

компилятор не проверяет ошибки ввода-вывода. Вызвав пре-

допределенную функцию IOResult, вы можете самостоятельно

проверить ошибки ввода-вывода.

* Когда выключена числовая обработка Numeric Processing

({$N-}), компилятор генерирует код, способный выполнять

все операции с плавающей точкой с помощью встроенного

6-байтового типа Real. Если параметр Numeric Processing

включен, ({$N+}), компилятор использует сопроцессор 80х87

или эмулирует сопроцессор с помощью программного обеспе-

чения, в зависимости от наличия сопроцессора 80х87. Полу-

ченный в результате код может использовать четыре дополни-

тельных вещественных типа (Single, Double, Extended и

Comp).

* Когда выключена проверка диапазона Stack Checking ({$R-}),

компилятор не выполняет проверку на ошибки индексирования

массива и присваивание значения вне диапазона.

* При выключенной проверке стека Stack Checking ({$S-}) ком-

пилятор не обеспечивает достаточного пространства в стеке

для каждого вызова процедуры или функции.

* Когда включена нестрогая проверка строк-переменных Relaxed

String Var Checking ($V-}), компилятор не проверяет пара-

метры-переменные строкового типа. Это позволяет вам пере-

давать строки фактических параметров, имеющие длину, от-

личную от длины, определенной для формального парамет-

ра-переменной.

* При разрешении расширенного синтаксиса Extended Syntax

({$X+}) вы можете использовать вызовы функций как операто-

ры, поскольку результат функциональных вызовов может отб-

расываться.

Оптимизация вашего кода с помощью этих параметров имеет два

преимущества. Во-первых, это делает ваш код более компактным и

быстрым. Во-вторых, позволяет делать вам некоторые вещи, которые

вы обычно делать не можете. Однако, все эти параметры вносят не-

который риск, поэтому используйте их аккуратно, и если ваша прог-

рамма начинает вести себя странно, вернитесь к исходной ситуации.

Условная компиляция

Чтобы облегчить ваши задачи, Borland Pascal предлагает

средство условной компиляции. Это означает, что можете компили-

ровать части своей программы на основе параметров или определен-

ных идентификаторов.

Условные директивы аналогичны по формату директивам компиля-

тора, с которыми вы уже познакомились. Они имеют следующий фор-

мат:

{$директива аргумент}

где "директива" - это такая директива как DEFINE, IFDEF и т.д., а

аргумент - необязательный аргумент. Между ними обязательно должен

присутствовать разделитель (пробел или табуляция). Все условные

директивы и их смысл приведены в Таблице 4.3.

Примечание: Полное описание директив условной компиля-

ции можно найти в Главе 2 ("Директивы компилятора") "Спра-

вочного руководства программиста".

Директива условной компиляции Таблица 4.3

ЪДДДДДВДДДДДДДї

і Директива і Описание і

ГДДДДДЕДДДДДДДґ

і {$DEFINE идентификатор} і Определяет "идентификатор" для і

і і других директив. і

ГДДДДДЕДДДДДДДґ

і {$UNDEF идентификатор} і Отменяет определение "иденти- і

і і фикатора". і

ГДДДДДЕДДДДДДДґ

і {$IFDEF идентификатор} і Компилирует следующий код, ес- і

і і ли определен "идентификатор". і

ГДДДДДЕДДДДДДДґ

і {$IFNDEF идентификатор} і Компилирует следующий код, ес- і

і і ли "идентификатор" не опреде- і

і і лен. і

ГДДДДДЕДДДДДДДґ

і {$IFOPT x+} і Компилирует следующий код, ес- і

і і ли разрешена директива x. і

ГДДДДДЕДДДДДДДґ

і {$IFOPT x-} і Компилирует следующий код, ес- і

і і ли запрещена директива x. і

ГДДДДДЕДДДДДДДґ

і {ELSE} і Компилирует следующий код, ес- і

і і ли предыдущее выражение IFxxx і

і і не равно True. і

ГДДДДДЕДДДДДДДґ

і {$ENDIF} і Отмечает конец блока IFxxx или і

і і ELSE. і

АДДДДДБДДДДДДДЩ

Директивы DEFINE и UNDEF

Директивы IFDEF и IFNDEF проверяют, определен ли заданный

идентификатор. Эти идентификаторы определяются с помощью DEFINE и

UNDEF. (Можно также определять идентификаторы в командной строке

или в IDE.)

Чтобы определить идентификатор, включите в программу следую-

щую директиву:

{$DEFINE идентификатор}

где "идентификатор" в плане длины, разрешенных символов и других

спецификаций подчиняется обычным правилам для имен идентификато-

ров. Например, вы можете записать:

{$DEFINE debug}

Этим для остальной части компилируемого модуля или до следу-

ющего оператора:

{$UNDEF debug}

определяется идентификатор debug.

Директива UNDEF "разопределяет" идентификатор. Если иденти-

фикатор не определен, то она не действует.

Определение условных идентификаторов в IDE

Вместо того, чтобы вставлять директиву DEFINE в свой исход-

ный код, вы можете также определить условные идентификаторы и

блоке ввода Conditional Defines (Условные определения). Определи-

те идентификаторы, введя их в блоке ввода и разделив точками за-

пятой. Например, в следующем примере определяются два условных

идентификатора - TestCode и DebugCode:

TestCode:DebugCode

Предопределенные идентификаторы

Кроме определяемых вами идентификаторов вы можете также про-

верять отдельные идентификаторы, определяемые компилятором:

Предопределенные условные идентификаторы Таблица 4.4

ЪДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДї

і Идентификатор і Показывает і

ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДґ

і CPU86 і Данная версия Borland Pascal предназначенаі

і і для семейства процессоров 80х86. і

ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДґ

і CPU87 і Присутствует арифметический сопроцессорі

і і 80х87. і

ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДґ

і DPMI і Данная версия предназначена для операцион-і

і і ной среды защищенного режима DOS. При соз-і

і і дании приложений для защищенного режимаі

і і DOS данный идентификатор доступен дляі

і і BP.EXE. і

ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДґ

і MSDOS і Данная версия предназначена для операци-і

і і онной системы MS-DOS. Данный идентификаторі

і і доступен в BP.EXE только при создании при-і

і і ложений DOS реального или защищенного ре-і

і і жима и в TURBO.EXE. і

ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДґ

і VER70 і Данная версия является версией 7.0 компи-і

і і лятора. і

ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДґ

і WINDOWS і Данная версия предназначена для операци-і

і і онной среды Windows. Данный идентификаторі

і і доступен в BP.EXE и в BPW.EXE, когда целе-і

і і вой платформой является Windows. і

АДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДЩ

Подробнее о предопределенных условных идентификаторах компи-

лятора рассказывается в Главе 2 ("Директивы компилятора") "Руко-

водства программиста".

Идентификаторы IFxxx, ELSE и ENDIF

Смысл условных директив в том, что если определен или нет

конкретный идентификатор либо если установлен или нет конкретный

параметр, вы можете выбирать для компиляции некоторые части ис-

ходного кода. Они имеют следующий общий формат, где IFxxx - это

директивы IFDEF, INDEF или IFOPT, за которыми следует соответс-

твующий аргумент, а "исходный код" - любое количество исходного

кода Паскаля.

{$IFxxx}

исходный код

{$ENDIF}

Если выражение в директиве IFxxx принимает значение True, то

"исходный код" компилируется; в противном случае он игнорируется

и интерпретируется как обычный комментарий в программе.

Часто у вас имеются альтернативные фрагменты кода. Если вы-

ражение принимает значение True, то компилируется один фрагмент

кода, а если False - другой. Компилятор позволяет сделать это с

помощью директивы $ELSE:

{$IFxxx}

исходный код A

{$ELSE}

исходный код B

{$ENDIF}

Если выражение в IFxxx равно True, то компилируется "исход-

ный код A", в противном случае компилируется "исходный код B".

Все директивы IFxxx должны завершаться с одном исходном фай-

ле. Это означает, что они не могут начинаться в одном исходном

файле и заканчиваться в другом. Однако, в директиве IFxxx может

указываться включаемый файл:

{$IFxxx}

{$I file1.pas}

{$ELSE}

{$I file2.pas}

{$ENDIF}

Таким образом, на основе некоторого условия вы можете выби-

рать альтернативные включаемые файлы

Допускается использовать вложенные конструкции IFxxx..ENDIF,

так что вы можете записать, например, следующее:

{$IFxxx} { первая директива IF }

.

.

.

{$IFxxx} { первая директива IF }

.

.

.

{$ENDIF} { завершает вторую директиву IF }

.

.

.

{$ENDIF} { завершает первую директиву IF }

Директивы IFDEF и IFNDEF

Директивы IFDEF и IFNDEF позволяют вам условно компилировать

код на основе определения или неопределения некоторых идентифика-

торов.

Директивы IFDEF и IFNDEF обычно используются для включения в

компилируемый код отладочной информации. Например, если вы помес-

тите в начало каждого модуля следующий код:

{$IFDEF debug}

{$D+,L+}

{$ELSE}

{$D-,L-}

{$ENDIF}

а в начало программы следующую директиву:

{$DEFINE debug}

и компилируете свою программу, для использования с Турбо отлад-

чиком генерируется полная отладочная информация. Аналогично, вы

можете иметь фрагменты кода, компилируемые только при отладке. В

этом случае можно записать:

{$IFDEF debug}

исходный код

{$ENDIF}

где "исходный код" компилируется только в том случае, если в дан-

ной точке определен идентификатор debug.

Директива IFOPT

Иногда включить или исключить код желательно в зависимости

от того, какой выбран параметр компилятора (проверка диапазона,

проверка ввода-вывода и т.д.). Вы можете сделать это с помощью

директивы IFOPT, которая имеет две формы:

{$IFOPT x+}

и

{$IFOPT x-}

где x - один из параметров компилятора. При использовании первой

формы содержащийся ниже код будет компилироваться, если параметр

компилятора в данный момент разрешен; при использовании второй

формы код компилируется при запрещении параметра. Например, чтобы

выбрать тип данных для списка переменных на основе того, разреше-

на или нет поддержка сопроцессора 80х87, можно использовать сле-

дующий исходный код:

var

{$IFOPT N+}

Radius,Circ,Area: Double;

{$ELSE}

Radius,Circ,Area: Real;

{$ENDIF}

Примечание: Полное описание всех параметров компилято-

ра вы можете найти в Главе 2 ("Директивы компилятора")

"Справочного руководства программиста".

Просмотр исходного кода

IDE защищенного режима DOS содержит новое программное инс-

трументальное средство просмотра объектов - ObjectBrowser. Оно

позволяет вам исследовать программы и модули в программах и мно-

гое другое. Даже если разрабатываемое вами приложение не исполь-

зует объектно-ориентированное программирование, вы найдете

ObjectBrowser чрезвычайно полезным средством. Вы можете просмат-

ривать иерархию объектов, модулей и всех процедур, функций, пере-

менных, типов, констант и другие используемые в программе иденти-

фикаторы. С помощью ObjectBrowser вы можете делать следующее:

* Просмотреть в своей прикладной программе иерархию объек-

тов. Затем выбрать объект и просмотреть все его процедуры,

функции и другие содержащиеся в программе идентификаторы.

При проверке идентификатора вы можете вывести перечень

всех ссылок на него в процедурах, функциях программы и,

если хотите, перейти на то место в исходном коде, где он

используется.

* Вывести список всех глобальных идентификаторов, используе-

мые в вашей программе, и увидеть их описания. Если вы вы-

берите одну переменную, то можете вывести список всех ссы-

лок не нее в своей программе и, если хотите, перейти на то

место в исходном коде, где она используется.

* Вывести список всех используемых в программе модулей, за-

тем выбрать один из них и просмотреть список всех иденти-

фикаторов его интерфейсной части.

* Выбрать идентификатор в исходном коде, затем просмотреть

детальную информацию по нему, нажав клавишу Ctrl и однов-

ременно щелкнув правой кнопкой "мыши".

* Открыть множество окон просмотра, сравнить идентификаторы,

выводимые в различных окнах, а затем вернуться в предыду-

щее открытое в средстве просмотра окно.

Перед использованием ObjectBrowser убедитесь, что в диалого-

вом окне OptionsіCompiler установлены следующие параметры:

* Debug Information (Информация для отладки).

* Locals Symbols (Локальные идентификаторы).

* Symbol Information (Информация об идентификаторах).

Убедитесь также, что в диалоговом окне Debugging/Browsing

(OptionsіDebugger) установлен параметр Integrated Debugging/

Browsing (Отладка с использование встроенного отладчика/Прос-

мотр).

Скомпилируйте программу, которую вы хотите просматривать.

Для активизации ObjectBrowser выберите в меню Search (Поиск)

команду Objects (Объекты), Units (Модули) или Globals (Глобальные

идентификаторы). Вы можете также поместить курсор на идентифика-

тор в исходном коде и выбрать для вывода ObjectBrowser команду

SearchіSymbol (ПоискіИдентификатор).

Вы можете также сделать так, чтобы компилятор "запоминал"

информацию об идентификаторах между компиляциями. Если этот пара-

метр включен, и вы измените программу, но следующая компиляция

завершиться неудачно, то вам все равно будет доступна информация

об идентификаторах, сохраненная с последней компиляции. Благодаря

этому вы сможете просмотреть свою программу, что поможет вам оп-

ределить источник проблемы. Чтобы компилятор сохранял информацию

об идентификаторах между компиляциями, нужно сделать следующее:

1. Выбрать команду OptionsіEnviromentіStartup.

2. Установить параметр Preserve Symbols (Сохранение иденти-

фикаторов); по умолчанию он установлен.

3. Выбрать командную кнопку OK.

4. Для выхода из IDE выбрать команду FileіExit.

5. Снова запустить IDE.

Примечание: Поскольку Preserve Symbols - это параметр

запуска, изменение его установки не будет иметь действие,

пока вы не выйдите из IDE и не запустите ее снова.

Если у вас есть "мышь", то исходный код удобнее просматри-

вать, если задать активизацию ObjectBrowser правой кнопкой "мы-

ши". Затем, удерживая нажатой клавишу Ctrl, вы можете использо-

вать правую кнопку "мыши" для указания и проверки объекта, проце-

дуры, функции, переменной или другого идентификатора в вашем ис-

ходном коде и его анализа (вывода детальной информации).

Примечание: Для быстрого просмотра идентификатора, на

котором в исходном коде позиционирован курсор, вы можете

также выбрать в локальном меню окна редактирования команду

Browse Symbol at Cursor (Просмотр идентификатора в позиции

курсора).

Чтобы задать просмотр с помощью "мыши", выполните следующие

шаги:

1. Выберите команду OptionsіEnviromentіMouse.

2. Выберите параметр Browse as the Ctrl + Right Mouse Button

(Просмотр по клавише Ctrl + правая кнопка "мыши").

3. Выберите командную кнопку OK.

Просмотр объектов

Команда SearchіObjects открывает окно, в котором выводятся

все используемые в программе объекты, упорядоченные в иерархичес-

кой структуре. В верхней части окна ObjectBrowser показывает ба-

зовый тип и выводит ниже и справа от базового типа потомков. Про-

яснить соотношения "предок-потомок" помогают соединяющие линии.

Примечание: Подробную информацию о типах объектов вы

можете найти в Главе 9 ("Объектно-ориентированной програм-

мирование").

±File±Edit±Search±±Run±±Compile±Debug±Tools±Options±Window±Help±±

ЙН[*]НННННННННННННННННННННН Browse: Object НННННННННННННННН2Н[*]»

є Global Scope є

єДґ I ГДДДДДДДє

єДObjects±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±^

є ГДДДДLocation Ы

є і ГДДДBlock ±

є і і ГДДДBall ±

є і і АДДДBrick ±

є і ГДДДCursor ±

є і і АДДДSaveScreen ±

є і ГДДДObstacle ±

є і і ГДДДBoundary ±

є і і і ГДДДLeftBound ±

є і і і ГДДДLowerBound ±

є і і і ГДДДRightBound ±

є і і і АДДДUpperBound ±

є і і ГДДДPaddle ±

є і і АДДДWall ±

є і АДДДTextString ±

є і АДДДCounter ±

є і АДДДDownCounter ±

є і АДДДLimitCounter v

И<±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±>ДЩ

°F1°Help°<Щ°Browse°°Ctrl°<Щ°Go°to°source°Space°Track°src°F10°Menu

Рис. 4.4 Просмотр иерархии объектов прикладной программы.

Если иерархия объектов у вас слишком большая, вы можете за-

дать, чтобы потомки конкретного объекта на экран не выводились.

* С помощью клавиатуры сделайте следующее:

1. Выберите объект.

2. Нажмите клавишу - (минус).

* При наличии "мыши" просто щелкните "мышью" на горизонталь-

ной линии, соединяющей объект с иерархией.

Теперь после объекта выводится + (плюс), и он подсвечивает-

ся, показывая, что потомки данного объекта на экран не выводятся.

Вы можете вывести потомков объекта снова.

* С помощью клавиатуры:

1. Выделите объект с символом +.

2. Нажмите клавишу +.

* При наличии "мыши" щелкните ей на горизонтальной строке,

соединяющей объект с иерархией.

Потомки объекта появляются вновь.

Из иерархии объектов вы можете просматривать все описанные в

индивидуальном объекте идентификаторы. Выделите объект и нажмите

клавишу Enter, либо дважды щелкните на объекте кнопкой "мыши".

При просмотре описанных в объекте идентификаторов вы можете

задать различные виды вывода:

* Для вывода информации о наследовании для просматриваемого

объекта щелкните "мышью" на букве I в верхней части окна

ObjectBrowser или нажмите клавиши Ctrl+I.

* Для вывода на экран перечня строк программы или модуля,

где имеется ссылка на идентификатор объекта щелкните

"мышью" на букве R в верхней части окна ObjectBrowser или

нажмите клавиши Ctrl+R.

* Для вывода области действия объекта щелкните "мышью" на

букве S или нажмите клавиши Ctrl+S.

Чтобы найти идентификатор в списке выводимых идентификато-

ров, наберите первую букву имени идентификатора; ваш курсор быст-

ро перемещается на соответствующий идентификатор.

Чтобы ObjectBrowser мог находить, где расположены ваши ис-

ходные файлые, вам может потребоваться изменить маршрут каталога

модулей и включаемых файлов в диалоговом окне Optionsі

Directories.

Если после открытия окна просмотра вы модифицируете исходный

код, добавляя или удаляя строки программы, то программу лучше пе-

рекомпилировать. Хотя ObjectBrowser после модификации исходного

кода все равно сможет отслеживать информацию об идентификаторах,

номера строк исходного кода, выводимые в окне редактирования, не

будут обновляться, пока программа не будет перекомпилирована.

Изменения режима вывода информации ObjectBrowser

Вы можете управлять характером вывода в ObjectBrowser инфор-

мации.

Можно выбрать, какие идентификаторы должны выводить

ObjectBrowser:

1. Для вывода диалогового окна Browser Options выберите ко-

манду OptionsіBrowser.

2. В группе Symbols отметьте только те идентификаторы, кото-

рые вы хотите выводить в ObjectBrowser. Вы можете также

выбрать вывод идентификаторов, наследуемых от предков

объекта.

3. Выберите командную кнопку OK.

В ObjectBrowser выводятся только те идентификаторы, кото-

рые вы выбрали.

Вы можете также выбрать, какие идентификаторы выводить толь-

ко в активном окне просмотра. Для вывода диалогового окна Local

Browser Options (Локальные параметры просмотра) выберите в ло-

кальном меню окна просмотра команду Options или при отображении

окна просмотра нажмите клавиши Ctrl+O.

Если вы в качестве типа отображаемых идентификаторов выбере-

те типы, переменные и процедуры, а затем будете просматривать

объект Location в программе BREAKOUT.PAS (пример демонстрационной

программы в каталоге EXAMPLES\DOS\BREAKOUT), то увидите следующую

информацию об идентификаторах:

±File±Edit±Search±±Run±±Compile±Debug±Tools±Options±Window±Help±±

ЙН[*]НННННННННННННННННННННН Browse: Object НННННННННННННННН2Н[*]»

є Global Scope є

єДґ S і I і R ГДДДДДДДДДДДДДДДДДДДДДДДДє

є±var±±±±Location.X:±±Integer±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±^

є var Location.Y: Integer Ы

є var Location.Visible: Boolean ±

є var Location.Init(Integer, Integer) ±

є proc Location.Relocate(Integer, Integer) ±

є proc Location.MoveTo(Integer, Integer) ±

є proc Location.Show ±

є proc Location.Hide ±

є func Location.GetX: Integer ±

є func Location.GetY: Integer ±

є func Location.InVisible: Boolean ±

є ±

є ±

є v

И<Ы±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±>ДЩ

°F1°Help°<Щ°Browse°°Ctrl°<Щ°Go°to°source°Space°Track°src°F10°Menu

Рис. 4.5 Просмотр информации об идентификаторах.

Сокращения слева от перечисленных идентификаторов перечисля-

ют идентификаторы, представляющие вид выводимого идентификатора.

Заметим, что включение идентификаторов процедур также включает

идентификаторы функций.

ЪДДДДДДДДДДДДДДДВДДДДДДДДДДДї

і Идентификатор і Смысл і

ГДДДДДДДДДДДДДДДЕДДДДДДДДДДДґ

і const і Константа і

і func і Функция і

і label і Метка і

і proc і Процедура і

і type і Тип і

і var і Переменная или типизированная кон- і

і і станта. і

АДДДДДДДДДДДДДДДБДДДДДДДДДДДЩ

Для вывода предыдущего окна просмотра выберите команду

SearchіPrevious Browser или нажмите клавиши Ctrl+P.

Когда вы просматриваете выделенный идентификатор, окно

ObjectBrowser по умолчанию выводит информацию об области дейс-

твия. Если вы предпочитаете по умолчанию видеть информацию о

ссылках, то сделайте следующее:

1. Выберите команду OptionsіBrowser.

2. Выберите в качестве значения параметра Preferred Pane

Reference.

3. Выберите командную кнопку OK.

По умолчанию ObjectBrowser выводит для проверяемого иденти-

фикатора полную информацию об описании. Вы можете просмотреть все

поля и методы записей и объектов, включая полностью уточненные

идентификаторы. Если вы не хотите видеть полностью уточненные

идентификаторы, то сделайте следующее:

1. Выберите команду OptionsіBrowser.

2. Отмените параметр вывода Qualified Symbols.

3. Выберите командную кнопку OK.

Примечание: Вы не увидите видеть полностью уточненные

идентификаторы, пока не установите наследование в диалого-

вом окне Browser Options (OptionsіBrowser).

По умолчанию ObjectBrowser выводит идентификаторы в области

Scope в том порядке, в каком они описаны. Если вы предпочитаете

сортировать идентификаторы в алфавитном порядке, то сделайте сле-

дующее:

1. Выберите команду OptionsіBrowser.

2. Установите параметр вывода Sort Always.

3. Выберите командную кнопку OK.

Идентификаторы будут сортироваться только по именам, а не

по полностью уточненным именам. Например, считается, что

следующий список идентификаторов отсортирован в алфавит-

ном порядке:

THELPFILE.DONE

TOBJECT.FREE

THELPFILE.INDEX: PHELP

Когда вы открываете окно просмотра, затем просматриваете пе-

речисленный в нем идентификатор, то открывается новое окно прос-

мотра, но предыдущее окно остается. Вы можете изменить это пове-

дение таким образом, что новое окно просмотра будет заменять пре-

дыдущее:

1. Выберите команду OptionsіBrowser.

2. Установите параметр Replace Current sub-browsing.

3. Выберите командную кнопку OK.

Чтобы текущее окно просмотра сохранялось, когда вы выбираете

перечисленный в его списке идентификатор, сделайте следующее:

1. Выберите команду OptionsіBrowser.

2. Установите параметр New Browser sub-browsing.

3. Выберите командную кнопку OK.

Возможно, в большинстве случаев вы предпочитаете использо-

вать параметр Replace Current или New Browser, но иногда исполь-

зуете альтернативный параметры. Быстро выбрать альтернативный па-

раметр можно следующим образом:

1. Нажмите и удерживайте в нажатом состоянии клавишу Shift.

2. Выберите следующее действие просмотра.

Например, если действует параметр New Browser, то при на-

жатии клавиши Shift следующее открываемое окно просмотра

будет замещать текущее.

Отслеживание и редактирование ссылок на строки

Когда ObjectBrowser выводит ссылочную информацию, вы можете

выбирать и редактировать выводимые в ссылке строки программы или

отслеживать ссылки на идентификатор. Отслеживание означает, что

IDE, при перемещении по ссылкам в окне просмотра, подсвечивает в

программе одну строку за другой.

Чтобы отредактировать выводимую в ссылке строку программы,

сделайте следующее:

1. Выделите ссылку в окне просмотра.

2. Нажмите клавиши Ctrl+Enter или Ctrl+G.

Ваш курсор перемещается на строку программы в исходном

коде, ссылка на которую содержится в окне просмотра. Те-

перь вы можете редактировать строку программы.

По умолчанию, когда ваш курсор перемещается на строку ис-

ходного кода программы, окно ObjectBrowser закрывается.

Если вы предпочитаете, чтобы окно просмотра оставалось

открытым, то отмените параметр Close On Go To Source в

диалоговом окне Preferences.

Примечание: Параметр Close On Go To Source влияет

также на окно сообщений Messages (см. ниже).

Для отслеживания строк программы:

1. В окне просмотра выделите ссылку, которую вы хотите отс-

леживать.

2. Нажмите клавишу пробела.

Если вы всегда хотите отслеживать ссылки по исходному ко-

ду, установите параметр Auto Track Source и группе

Options диалогового окна Preferences. Тогда при прокрутке

ссылок строки в исходном коде программы будут прокручи-

ваться автоматически, и пробел вам нажимать не нужно.

Примечание: Параметр Auto Track Source влияет также

на окно сообщений Messages (см. ниже).

Теперь строки программы, на которые имеются ссылки в окне

просмотра, отслеживаются в зависимости от того, как вы установили

параметры отслеживания в диалоговом окне OptionsіEnviromentі

Preferences: если файл, на который имеется ссылка, не находится в

окне редактирования, то IDE открывает файл, и он выводится либо в

новом, либо в текущем окне редактирования.

* Если вы хотите, чтобы файл выводился в новом окне редакти-

рования, выберите в качестве значения параметра Source

Tracking New Window.

* Если вы хотите, чтобы файл замещал текущий в активном окне

редактирования, выберите в качестве значения параметра

Source Tracking Current Window.

Примечание: Параметр Source Tracking влияет также на

окно сообщений Messages (см. ниже).

Если выбранный модуль хранится в библиотеке исполняющей сис-

темы Borland Pascal или является одним из стандартных модулей, то

вы не сможете просматривать или редактировать исходный код, пос-

кольку эти модули скомпилированы без включения отладочной инфор-

мации.

Просмотр модулей

Команда SearchіUnits открывает диалоговое окно, в котором

выводятся используемые в вашей программе модули, перечисленные в

алфавитном порядке. Для просмотра идентификаторов, описанных в

интерфейсной части модуля, выделите конкретный модуль и нажмите

клавишу Enter или дважды щелкните не нем кнопкой "мыши". Анало-

гично тому, как это делается с объектами, вы можете видеть об-

ласть действия ссылочной информации для идентификатора. Если мо-

дуль, на который имеется ссылка, не является одним из поставля-

емых с Borland Pascal стандартных модулей, и скомпилирован таким

образом, что включает в себя всю необходимую для интегрированной

отладки/просмотра информацию, то вы можете при соответствующей

ссылке отслеживать и редактировать исходный код модуля.

В следующем примере модуль Walls описывается в строке 4 фай-

ла WALLS.PAS и вызывается на строке 37 BREAKOUT.PAS.

ЪДДДДДДДДДДДДДДДДД Browse: Units ДДДДДДДДДДДДД2ДДї

і Global scope і

ГДґ S ГДДДДДДДДДДДДДДДДДґ

і unit Bounds і

і unit Breakout і

і unit Bricks і

і unit Count і

і unit Crt ЙН[*]ННННН Browse: Walls НН3ННН[^]Н»

і unit Dos є unit Walls є

і unit Screen єДґ S і R Гє

і unit System є WALLS.PAS(4) є

і±unit±±Walls±±±± є°BREAKOUT.PAS(37)°°°°°°°°°°°°°°°°°°є

і є є

і є є

і ИНН2/2ННННННННННННННННННННННННННННННј

і і

і і

АДДДДДДДДДДДДДДДДДДДДДДДЩ

Рис. 4.6 Просмотр модулей в вашей прикладной программе.

Просмотр глобальных идентификаторов

Команда SearchіGlobal открывает окно, в котором выводятся

используемые в программе глобальные идентификаторы, перечисленные

в алфавитном порядке. Как и в случае объектов, для просмотра

строк в программе, ссылающихся на этот идентификатор, описаний

идентификатора и иерархии наследования вы можете открывать допол-

нительные окна ObjectBrowser. При выводе ссылочной информации вы

можете отслеживать или редактировать строки программы. Например,

на следующем рисунке показан список глобальных идентификаторов,

используемых в программе BREAKOUTS.PAS:

ЙН[*]НННННННННННННННННННННН Browse: Object НННННННННННННННН2Н[^]»

є Global Scope є

єДґ S ГДДДДДДДє

є±func±±±Abs(..)±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±^

є func Addr(...) Ы

є const AnyFile = 63 ±

є proc Append(...) ±

є const Archive = 32 ±

є func ArcTan(...) ±

є proc Assing(...) ±

є proc AssingCrt(var Text) ±

є func Assigned(...) ±

є var b: Ball ±

є type Ball = object(Block) ±

є var Balls: DownCounter ±

є proc Beep ±

є const Block = 0 ±

є const Blink = 128 ±

є type Block = object(Location) ±

є proc BlockRead(...) ±

є const Blue = 1 v

И<Ы±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±>ДЩ

Рис. 4.7 Просмотр глобальных идентификаторов, используемых в

программе.

Просмотр идентификаторов в исходном коде

Вы можете просматривать идентификаторы в своем исходном ко-

де. Поместите курсор на идентификатор и выберите один из следую-

щих методов:

* Для вывода диалогового окна Browse Symbol выберите в меню

Search команду Symbol. Используйте идентификатор, выведен-

ный в диалоговом окне, или введите другой идентификатор и

выберите командную кнопку OK.

* Для вывода локального меню окна редактирования нажмите

клавиши Alt+F10 или щелкните правой кнопки "мыши" и выбе-

рите команду Browse Symbol at Cursor.

* Если для просмотра идентификаторов вы задали правую кнопку

"мыши" (выбором команды OptionsіEnviromentіMouse и Browse

at Cursor), то нажмите клавишу Ctrl и, удерживая ее, щел-

кните правой кнопкой "мыши".

Тип информации, которую вы видите, зависит от типа информа-

ции, доступной для выбранного идентификатора:

* Если для выделенного вами идентификатора информация об об-

ласти действия недоступна, то ObjectBrowser выводит для

него ссылочную информацию. Например, для простой константы

доступна только ссылочная информация.

* Если выделенный вами идентикатор не имеет доступной инфор-

мации об области действия, ObjectBrowser выводит для этого

идентификатора информацию об области действия. Он также

дает вам возможность видеть ссылочную информацию.

* Если выделенный вами идентификатор представляет собой

структурный тип, то ObjectBrowser выводит для этого типа

информацию об области действия. Он дает вам также возмож-

ность видеть информацию о наследовании и ссылочную инфор-

мацию. Если вы выберите информацию о наследовании, то уви-

дите непосредственного предка этого типа и непосредствен-

ных потомков, если они имеются.

Если вы выбрали просмотр структурного типа, ObjectBrowser

выводит на экран полностью уточненные имена, если удовлетворяются

следующие два условия:

* В диалоговом окне Browser Options (OptionsіBrowser) или в

диалоговом окне Local Browser Options (локальное меню

Options окна просмотра) выбран параметр Inherited symbol.

* В диалоговом окне Browser Options (OptionsіBrowser) или в

диалоговом окне Local Browser Options (локальное меню

Options окна просмотра) выбран параметр Qualified Symbols.

Например, на следующем рисунке показана полная информация об

описании области действия для переменной b типа Ball:

±File±Edit±Search±±Run±±Compile±Debug±Tools±Options±Window±Help±±

ЙН[*]НННННННННННННННННННННН Browse: b ННННННННННННННННННННН2Н[*]»

є var b: Ball є

єДґ S і I і R ГДДДДДДДДДДДДДДДДДДДДДДДДє

є±var±±±±Location.X:±±Integer±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±^

є var Location.Y: Integer Ы

є var Location.Visible: Boolean ±

є var Location.Init(Integer, Integer) ±

є proc Location.Relocate(Integer, Integer) ±

є proc Location.MoveTo(Integer, Integer) ±

є func Location.GetX: Integer ±

є func Location.GetY: Integer ±

є func Location.InVisible: Boolean ±

є var Block.Color: Integer ±

є var Block.Width: Integer ±

є var Block.BChar: Char ±

є proc Block.Show ±

є proc Block.Hide ±

є var Ball.XVel: Integer ±

є var Ball.YVel: Integer ±

є proc Ball.Init(Integer, Integer, Integer, Integer, Integer) ±

є func Ball.NextX: Integer ±

є func Ball.NextY: Integer ±

є proc Ball.MoveX v

И<Ы±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±>ДЩ

°F1°Help°<Щ°Browse°°Ctrl°<Щ°Go°to°source°Space°Track°src°F10°Menu

Рис. 4.8 Просмотр полной информации описания области дейс-

твия.

Если ObjectBrowser выводит сообщение, говорящее, что ка-

кой-то идентификатор не найден, проверьте и убедитесь, что вы за-

дали в ObjectBrowser проверку допустимого идентификатора, и что

идентификатор находится в нужной области действия. Например, при

выборе команды SearchіSymbol курсор может быть позиционирован на

комментарии. Либо курсор может находиться вне области действия, в

которой ObjectBrowser может найти информацию об идентификаторе.

Например, курсор может находиться на формальном параметре в опи-

сании функции, а не в реализации функции. В этом случае

ObjectBrowser не может найти идентификатор, но если вы найдете

параметр в реализации функции, то сможете просмотреть его.

Просмотр функций ObjectBrowser

В Таблице 4.5 перечислены клавиши и команды меню, активизи-

рующие функции ObjectBrowser:

Функции ObjectBrowser Таблица 4.5

ЪДДВДДДДДДДДДДї

і Чтобы выполнить: і Сделайте следующее: і

ГДДЕДДДДДДДДДДґ

і Просмотр объектов і Выберите команду SearchіObjects. і

ГДДЕДДДДДДДДДДґ

і Просмотр модулей і Выберите команду SearchіUnits. і

ГДДЕДДДДДДДДДДґ

і Просмотр глобальных і Выберите команду SearchіGlobals. і

і идентификаторов і і

ГДДЕДДДДДДДДДДґ

і Просмотр идентификатора і Поместите курсор на идентификатореі

і і своей программы, выберите командуі

і і SearchіSymbol или удерживайте на-і

і і жатой клавишу Ctrl и щелкните пра-і

і і вой кнопкой "мыши". і

ГДДЕДДДДДДДДДДґ

і Выбрать Browser Options і Выберите команду OptionsіBrowser. і

ГДДЕДДДДДДДДДДґ

і Выбрать параметр Source і Выберите команду OptionsіEnviro-і

і Tracking Options і mentіPreferences. і

ГДДЕДДДДДДДДДДґ

і Выбрать Mouse Options і Выберите команду OptionsіEnviro-і

і і mrntіMouse. і

ГДДЕДДДДДДДДДДґ

і Открыть предыдущее окно і Выберите команду SearchіPreviousі

і просмотра і Browser, выберите в локальном менюі

і і окна просмотра команду Previousі

і і или нажмите клавиши Ctrl+P. і

ГДДЕДДДДДДДДДДґ

і Выбрать Local Browser і Нажмите клавиши Ctrl+O или выбери-і

і Options і те команду Options в локальном і

і і меню окна просмотра. і

ГДДЕДДДДДДДДДДґ

і Отредактировать исходный і Нажмите Ctrl+Enter в ObjectBrowserі

і код і нажмите клавиши Ctrl+G или выбери-і

і і те в локальном меню окна просмотраі

і і команду Goto Source. і

ГДДЕДДДДДДДДДДґ

і Отслеживать исходный і Нажмите в ObjectBrowser пробелі

і код і нажмите клавиши Ctrl+T или выбери-і

і і те в локальном меню окна просмотраі

і і Track Source. і

ГДДЕДДДДДДДДДДґ

і Вывести ссылочную і Нажмите в ObjectBrowser клавишиі

і информацию і Ctrl+R или щелкните "мышью" наі

і і букве R в рамке окна. і

ГДДЕДДДДДДДДДДґ

і Вывести информацию і Нажмите в ObjectBrowser клавишиі

і об области действия і Ctrl+S или щелкните "мышью" наі

і і букве S в рамке окна. і

ГДДЕДДДДДДДДДДґ

і Вывод информации о і Нажмите в ObjectBrowser клавишиі

і наследовании і Ctrl+I или щелкните "мышью" наі

і і букве I в рамке окна. і

ГДДЕДДДДДДДДДДґ

і Изменить на обратный і Нажмите клавишу Shift, и, удержи-і

і режим вывода подокна і вая ее, выполните следующее дейст-і

і і вие. і

АДДБДДДДДДДДДДЩ

Выполнение в IDE других программ

Без выхода из IDE вы можете запускать другие программы и

утилиты. При установке пакета Borland Pascal IDE устанавливается

для выполнения таких инструментальных программных средств как

GREP, Turbo Assembler, Turbo Debugger и Turbo Profiler.

Чтобы запустить в интегрированной интерактивной среде прог-

рамму, сделайте следующее:

1. Откройте меню Tools (Инструментальные средства).

Вы увидите список программ и утилит, которые может запус-

кать.

2. Выберите в меню Tools программу, которую вы хотите запус-

тить.

При выборе программы ей передается управление. После выпол-

нения программы управление возвращается обратно в IDE.

Настройка меню Tools

Программы, которые вы найдете полезными, можно добавить в

меню Tools и запускать их потом из IDE.

Чтобы добавить программы в меню Tools, сделайте следующее:

1. Для вывода диалогового окна Tools выберите команду

OptionsіTools.

В блоке списка заголовков программ Program Titles вы уви-

дите краткое описание уже инсталлированных и готовых к

выполнению программ.

2. Для вывода диалогового окна Modify/New Tool (Модифика-

ция/Новое инструментальное средство) выберите команду

New.

3. В блоке ввода заголовка программы Program Title наберите

имя программы, как вы хотите выводить его в меню Tools.

Если вы хотите, чтобы программа вызывалась по оперативным

клавишам, укажите непосредственно перед и после того сим-

вола, который должен использоваться в качестве оператив-

ной клавиши, символ тильды (~). Этот символ будет выво-

диться в меню Tools жирным шрифтом и специальным шрифтом,

и при нажатии этой клавиши вы выберете программу. Напри-

мер, чтобы добавить в меню Tools редактор Brief и сделать

оперативной клавишей клавишу B, наберите:

~B~rief

4. Если вы хотите, чтобы ваша программа имела связанную с

ней оперативную клавишу, выберите один из параметров Hot

Key. Когда вы нажмете присвоенную оперативную клавишу,

программа начинает работать. Например, утилите GREP прис-

воены оперативные клавиши Shift+F2. В любой момент, чтобы

использовать GREP, просто нажмите Shift+F2.

5. В блоке ввода Program Path (Маршрут программы) наберите

имя программы.

Если вы не введете полного имени, то могут быть найдены

только программы в текущем каталоге или программы по

обычному маршруту DOS.

6. В блоке ввода Command Line (Командная строка) наберите

параметры или макрокоманды, которые вы хотите передать

программе.

Полную справочную информацию по макрокомандам, которые

можно использовать в блоке Command Line в Modify/New Tool

вы можете найти в оперативном справочнике Help Borland

Pascal.

7. Выберите командную кнопку OK.

Для редактирования имеющейся в меню Tools программы сделайте

следующее:

1. Выберите команду OptionsіTools.

2. В блоке списка Program Titles выберите нужную программу

для редактирования.

3. Выберите Edit (Редактирование).

4. Внесите изменения в заголовок программы, маршрут програм-

мы или командную строку.

5. Выберите командную кнопку OK.

Чтобы удалить указанную в меню Tools программу:

1. Выберите команду OptionsіTools.

2. Выберите программу, которую вы хотите удалить.

3. Выберите Delete (Удаление).

4. Выберите командную кнопку OK.

Работа с окном Messages

Некоторые инструментальные средства посылают вывод программы

черед фильтр DOS - программу, конвертирующую вывод в формат, ко-

торый можно выводить в окне сообщений Messages. Более подробную

информацию об использовании и написании ваших собственных филь-

тров DOS вы можете получить в оперативном справочнике Help. Одним

из таких инструментальных средств, использующих окно Messages,

является GREP, а ее фильтр называется GREP2MSG.EXE. Исходный код

CREP2MSG.PAS вы можете найти в каталоге UTILS.

При работе такого инструментального средства как GREP выво-

димая информация передается в появляющееся окно сообщений

Messages. Выводимые сообщения вы можете прокручивать. В окне

Messages вы можете выбирать и редактировать строку программы, на

которую имеется ссылка в сообщении, либо вы можете отслеживать

свои сообщения (подсвечивать одну за другой строки исходного кода

программы, при прохождении сообщений в этом окне).

Чтобы отредактировать строку программы, на которую имеется

ссылка в сообщении, сделайте следующее:

* Если вы используете "мышь", дважды щелкните "мышью" на ин-

тересующем вам сообщении.

* При работе с клавиатурой выберите сообщение со ссылкой на

нужную строку программы и нажмите Enter.

* Ваш курсор перемещается на строку программы в исходном ко-

де, на которую ссылается сообщение в окне Messages. Теперь

вы можете отредактировать строку программы.

По умолчанию, когда курсор переходит на строку исходного

кода программы, окно Messages закрывается. Если вы предпо-

читаете, чтобы окно Messages оставалось открытым, отмените

выбор параметра Close On Go To Source в диалоговом окне

Preferences.

Примечание: Параметр Close On Go To Source влияет

также на ObjectBrowser (см. выше).

Чтобы отслеживать строки программы:

1. В окне Messages выберите сообщение со ссылкой на строку

программы, которую вы хотите отслеживать первой.

2. Нажмите клавишу пробела.

Если вы всегда хотите отслеживать сообщения в исходном

коде, установите в группе Options диалогового окна

Preferences параметр Auto Track Source. После этого при

прокрутке окна сообщений в вашем исходном коде автомати-

чески будут подсвечиваться соответствующие строки; вам не

нужно будет нажимать на клавишу пробела.

Примечание: Параметр Auto Track Source влияет также

на ObjectBrowser (см. выше).

Теперь строки программы, на которые есть ссылки в сообщени-

ях, отслеживаются в зависимости от установленных в диалоговом ок-

не OptionsіEnviromentіPreferences параметров. Если соответствую-

щий файл не находится в окне редактирования, IDE открывает файл и

выводит его в новом окне редактирования или в текущем окне редак-

тирования.

* Если вы хотите, чтобы файл выводился в новом окне редакти-

рования, выберите в качестве значения параметра Source

Tracking New Window.

Примечание: Параметр Source Tracking влияет также на

ObjectBrowser (см. выше).

* Если вы хотите, чтобы файл замещал текущий файл в одном из

активных окон редактирования, выберите в качестве значения

параметра Source Tracking Current Window.

Если окно сообщений закрыто, с помощью команды Toolsі

Messages вы можете открыть его снова.

Настройка конфигурации IDE

При написании и редактировании программ вы можете установить

параметры редактирования и привилегированные параметры, выбрать

параметры компилятора и компоновщика или изменить по своему ус-

мотрению расположение и размер окон редактирования. IDE может за-

поминать установленные значения и файлы и использовать их в сле-

дующем сеансе редактирования.

Сохранение рабочей операционной среды

С помощью Auto Save вы можете сохранить параметры Editor

Files, Desktop и Enviroment в диалоговом окне OptionsіEnviroment.

* Если установлен параметр Editor Files, IDE при выходе из

интегрированной среды, выборе команды FileіDOS Shell, вы-

полнении или отладке программы сохраняет все модифициро-

ванные файлы, открытые в окне редактирования.

* Если установлен параметр Desktop, IDE при выходе из интег-

рированной среды, выборе команды FileіDOS Shell, выполне-

нии или отладке программы сохраняет имена всех файлов, с

которыми вы работали в оперативной области.

* Если установлен параметр Enviroment, IDE при выходе из ин-

тегрированной среды, выборе команды FileіDOS Shell, выпол-

нении или отладке программы сохраняет в файле конфигурации

выбранные вами все параметры редактирования, компоновки и

компиляции.

Использование файла конфигурации

Файл конфигурации сохраняет все параметры, установленные в

меню параметров Options, выбранные в диалоговом окне Find Text,

отслеживает все объединенные файлы Help, целевую платформу и имя

основного файла (если он имеется). Если в диалоговом окне

OptionsіEnviromentіPreferences установлен параметр Auto Save

Enviroment, то файл конфигурации обновляется при выходе из интег-

рированной среды, выборе команды FileіDOS Shell, выполнении или

отладке программы. При использовании компиляторов BP.EXE или

TURBO.EXE по умолчанию файл компилятором называется TP.EXE.

Чтобы создать новый файл конфигурации для другого проекта,

сделайте следующее:

1. Выберите команду OptionsіSave As.

2. В поле ввода Options File Name наберите новое имя.

3. Выберите командную кнопку OK.

Примечание: Об использовании файла конфигурации для

управления программным проектом рассказывается в следующей

главе.

Чтобы переключиться на другой существующий файл конфигура-

ции:

1. Выберите команду OptionsіOpen.

2. Задайте имя существующего файла конфигурации.

3. Выберите командную кнопку OK.

Чтобы модифицировать существующую конфигурацию:

1. Измените нужные параметры.

2. Выберите команду OptionsіSave.

IDE сохраняет все изменения в текущем файле конфигурации.

Использование файла оперативной области

ДДДДДДДДДДДДДДД

Если в диалоговом окне OptionsіEnvioromentіPreferences вы

установили параметр Auto Save Desktop, IDE при выходе из интегри-

рованной среды, выборе команды FileіDOS Shell, выполнении или от-

ладке программы обновляет файл оперативной области. Файл опера-

тивной области отслеживает все файлы, которые вы открывали, и

файлы, с которыми вы работали, но закрыли их в ходе сеанса прог-

раммирования (кроме файлов NONAMExx.PAS). Когда вы начнете новый

сеанс редактирования, ваши окна редактирования выводятся в том

виде, какой они имели при выходе. Когда вы откроете меню File, то

список закрытых файлов в меню File продолжает увеличиваться (мак-

симум до 5 значений).

Как определить, какой файл оперативной области использовать?

Вы можете непосредственно выбрать новый файл оперативной области,

но каждый раз, когда вы создаете файл конфигурации, IDE создает

новый файл оперативной области. Имя файла будет тем же самым, но

имя файла оперативной области вместо расширения .TP имеет расши-

рение .DSK. Например, если ваш файл конфигурации называется

MY.TP, то файл оперативной области будет называться MY.DSK.

По умолчанию IDE сохраняет файл оперативной области в том же

каталоге, что и текущий файл конфигурации. Если хотите, то можете

сохранять файлы конфигурации в текущем каталоге:

1. Выберите команду OptionsіEnviromentіPreferences.

2. В группе Desktop File выберите параметр Current

Directory.

Если вы хотите сохранять текущие параметры конфигурации, но

очищать оперативную область, так что IDE будет "забывать" список

всех файлов, с которыми вы работали, очищать все списки протоко-

лов и закрывать все окна, сделайте следующее:

1. Выберите команду OptionsіEnviromentіPreferences.

2. Убедитесь, что в диалоговом окне Preferences установлен

параметр Desktop, а параметр Enviroment выключен.

3. Перезапустите IDE.

IDE закрывает все ваши окна и сохраняет текущие парамет-

ры, но ваша оперативная область, списки протоколов и

списки закрытых файлов будут очищены.

Сохранение идентификаторов от одного сеанса к другому

Одновременно с сохранением файла оперативной области вы мо-

жете выбрать сохранение информации об идентификаторах в файле

идентификаторов (файл с расширением .PSM). Тогда при следующем

запуске IDE информация об идентификаторах, генерируемая при пос-

ледней компиляции, будет доступна, благодаря чему вы можете вы-

полнять немедленный просмотр и отладку.

Чтобы сохранять идентификаторы между сеансами, сделайте сле-

дующее:

1. Выберите команду OptionsіEnviromentіPreferences.

2. Убедитесь, что установлен параметр Auto Save Desktop.

3. В группе Desktop File Options выберите параметры Desktop

и Symbols.

4. Выберите командную кнопку OK.

Управление проектом

Если вы хотите сделать свое программирование проекта модуль-

ным и более легко управляемым, используйте основной файл. Задайте

в качестве основного файла главный файл программы и сделайте так,

чтобы он использовал несколько модулей или включаемых файлов, где

вы можете хранить большие фрагменты кода.

Чтобы задать, какой файл будет основным, выполните следующие

шаги:

1. Выберите команду CompileіPrimary File.

2. Когда выведется диалоговое окно, наберите имя своего фай-

ла или выберите его из окна списка Files.

3. Выберите командную кнопку OK.

Теперь, когда вы используете команду CompileіMake или Build,

компилируется основной файл, даже если он не является файлом в

активном окне редактирования.

Каждый проект, с которым вы работаете с IDE, имеет уникаль-

ные требования. Например, каждый проект имеет различный основной

и различные каталоги, где находятся ваши файлы. Вы можете настро-

ить IDE в соответствии со своим проектом.

Управление несколькими проектами

с файлом конфигурации для каждого из них

Секрет управления проектами в IDE состоит в использовании

для каждого проекта своего файла конфигурации. Когда вы начинаете

новый проект, создайте новый файл конфигурации:

1. Установите все параметры так, как это требуется для ново-

го проекта.

2. Задайте основной файл.

3. Для задания каталогов, где компилятор будет искать файлы

для вашего проекта используйте команду Optionsі

Directories.

4. В меню Options выберите команду Save As.

В диалоговом окне выводится подсказка для ввода имени но-

вого файла конфигурации.

5. Задайте имя нового файла конфигурации.

6. Выберите командную кнопку OK.

Если вы в этот момент выйдите из IDE, а параметры Auto Save

Desktop и Enviroment Options (OptionsіEnviromentіPreferences) ус-

тановлены, то, когда вы начинаете новый сеанс, IDE использует но-

вый файл конфигурации и файл оперативной области. Файлы, с кото-

рыми вы работаете, будут доступны для вас в окне редактирования

или в списке закрытых файлов в меню File, поскольку для вашего

проекта создается новый файл оперативной области.

Если вы храните каждый проект Паскаля в отдельном каталоге,

то ниже даны рекомендации по удобному управлению проектом. Когда

вы установите все параметры так, как это требуется для проекта, и

зададите основной файл (если он имеется), сделайте следующее:

1. В меню Options выберите команду Save As.

2. Задайте новое имя файла конфигурации, включив в каталог

проекта полный маршрут.

* Если вы используете BP.EXE, задайте в качестве нового

файла конфигурации BP.TP.

* Если вы используете TURBO.EXE, задайте в качестве ново-

го файла конфигурации TURBO.TP.

3. Выберите командную кнопку OK.

Сохранив в каталоге проекта файл BP.TP или TURBO.TP, вы

можете перейти в каталог проекта, запустить IDE, и IDE

автоматически загрузит в файл конфигурации в этом катало-

ге.

Если вы не хотите больше работать с файлом, заданным в ка-

честве основного файла, то можете использовать для очистки этого

файла следующие два метода:

* Выберите команду CompileіClear Primary File.

* Выберите в диалоговом окне Primary File параметр Primary

File и Clear (Очистка).

Если вы хотите работать с другим проектом, с помощью команды

OptionsіOpen загрузите новый файл конфигурации проекта.


Глава 5. Программирование в интегрированной интерактивной среде для Windows

Интегрированная среда (IDE) для Windows очень похожа на IDE

для DOS Borland Pascal. Большинство функций, которые вы выполняе-

те в IDE для DOS, аналогичным образом выполняется в IDE для

Windows. Если вы не читали предыдущую главу, потратьте некоторое

время и сделайте это.

Примечание: IDE для Windows может создавать прикладные

программы для Windows, защищенного режима DOS и реального

режима DOS.

В данной главе основное внимание уделяется уникальным средс-

твам IDE для Windows и поясняется некоторое различие между IDE

для DOS и для Windows.

Так как Borland Pascal for Windows работает под Windows, мы

подразумеваем, что вы уже знакомы с Windows. Если вы умеете рабо-

тать с Windows, то сможете работать и с IDE Borland Pascal for

Windows.

Запуск IDE для Windows

Для запуска IDE для Windows необходимо дважды щелкнуть

"мышью" над пиктограммой Borland Pascal for Windows в администра-

торе программ или выбрать ее с помощью клавиатуры и нажать клави-

шу Enter.

Вы можете также запустить IDE для Windows в ответ на подс-

казку DOS. Наберите:

WIN BWP

Продвигаясь на шаг дальше, вы можете в ответ на подсказку

DOS задать, какие файлы нужно открыть в окнах редактирования, и

какой нужно использовать файл конфигурации. При этом используется

следующий синтаксис:

WIN BWP [/Cфайл_конфигурации]файлы

Например, на следующей строке запускается Windows, и начина-

ет работать IDE для Windows, используя параметры в файле конфигу-

рации MYCONFIG.CFG и открывая два окна, одно из которых содержит

файл MYFILE.PAS, а другое - YOURFILE.INC:

WIN BWP /Cmyconfig myfile yourfile

Использование оперативной полосы

С помощью оперативной полосы SpeedBar и "мыши" вы можете

быстро выбирать команды и другие действия.

Командные кнопки в оперативной полосе представляют команды.

Это оперативные кнопки для "мыши", аналогично тому, как опреде-

ленные комбинации клавиш на клавиатуре являются оперативными кла-

вишами. Чтобы выбрать команду, щелкните на соответствующей ко-

мандной кнопке "мышью". Например, если вы щелкните "мышью" на ко-

мандной кнопке Open a File (Открыть файл), то реакция IDE будет

такой же, как при выборе команды Open меню File.

Оперативная полоса контекстно-зависима. То, какие командные

кнопки к ней выводятся, зависит от того, какое окно активно - ок-

но оперативной области или окно редактирования.

Оперативные полоса окна рабочей области выводится, когда в

IDE не открыты окна редактирования. В оперативной полосе рабочей

области выводятся следующие командные кнопки:

ЪДДДДДДДДДДДї ЪДДДДДДДДДДДї

і і і і

і і і і

і і і і

АДДДДДДДДДДДЩ АДДДДДДДДДДДЩ

Help (Контекстные экраны Make (Формирование)

справочной системы)

ЪДДДДДДДДДДДї ЪДДДДДДДДДДДї

і і і і

і і і і

і і і і

АДДДДДДДДДДДЩ АДДДДДДДДДДДЩ

Open a File Make and Run

(Открыть файл) (Формирование и

запуск)

ЪДДДДДДДДДДДї ЪДДДДДДДДДДДї

і і і і

і і і і

і і і і

АДДДДДДДДДДДЩ АДДДДДДДДДДДЩ

Exit the IDE Make and Run under

(Выход из IDE) Turbo Debugger

(Формирование и

запуск с отладчиком)

Рис. 5.1 Командные кнопки оперативной полосы рабочей облас-

ти.

Следующие командные кнопки выводятся в оперативной полосе

окна редактирования.

ЪДДДДДДДДДДДї ЪДДДДДДДДДДДї

і і і і

і і і і

і і і і

АДДДДДДДДДДДЩ АДДДДДДДДДДДЩ

Help on Editor Paste from Clipboard

(Справка по редактору) (Вставка из буфера)

ЪДДДДДДДДДДДї ЪДДДДДДДДДДДї

і і і і

і і і і

і і і і

АДДДДДДДДДДДЩ АДДДДДДДДДДДЩ

Open a File Undo (Отмена)

(Открытие файла)

ЪДДДДДДДДДДДї ЪДДДДДДДДДДДї

і і і і

і і і і

і і і і

АДДДДДДДДДДДЩ АДДДДДДДДДДДЩ

Save a file Compile

(Сохранение файла) (Компиляция)

ЪДДДДДДДДДДДї ЪДДДДДДДДДДДї

і і і і

і і і і

і і і і

АДДДДДДДДДДДЩ АДДДДДДДДДДДЩ

Search for text Make (Формирование)

(Поиск текста)

ЪДДДДДДДДДДДї ЪДДДДДДДДДДДї

і і і і

і і і і

і і і і

АДДДДДДДДДДДЩ АДДДДДДДДДДДЩ

Search again Make and Run

(Повторный поиск) (Формирование и запуск)

ЪДДДДДДДДДДДї ЪДДДДДДДДДДДї

і і і і

і і і і

і і і і

АДДДДДДДДДДДЩ АДДДДДДДДДДДЩ

Cut to Clipboard Make and Run under

(Вырезание в буфер) Turbo Debugger

(Формирование и

запуск с отладчиком)

ЪДДДДДДДДДДДї

і і

і і

і і

АДДДДДДДДДДДЩ

Copy to Clipboard

(Копирование в буфер

вырезанного изображения)

Рис. 5.2 Командные кнопки оперативной полосы окна редактиро-

вания.

Иногда определенные командные кнопки оперативной полосы вы-

водятся тусклыми. Это означает, что команда, представляемая дан-

ной кнопкой, в текущем контексте для вас недоступна. Например,

если окно редактирования открыто, и буфер вырезанного изображения

пуст, то кнопка Paste Text from Clipboard будет тусклой.

Настройка конфигурации оперативной полосы

При первом запуске IDE оперативная полоса представляет собой

горизонтальную группу командные кнопок, которая выводится непос-

редственно по строкой меню. Оперативная полоса может быть:

* горизонтальной полосой;

* вертикальной полосой в левой части оперативной области

IDE;

* всплывающим набором, который вы можете перемещать в любую

часть оперативной области.

Вы можете также выключить оперативную полосу.

Чтобы изменить конфигурацию оперативной полосы, выберите ко-

манду OptionsіEnviromentіPreferences и выберите нужный параметр

оперативной полосы.

Использование справочной системы Help

Справочная система Help дает вам возможность легкого доступа

к подробной информации о языке Borland Pascal, интегрированной

среде, библиотеке динамической компоновки, ObjectWindows, интер-

фейсе прикладных программ Windows (API) и дополнительных утили-

тах, предусмотренных в Borland Pascal. Вы можете просматривать

все эти темы в справочном окне Help или получать контекстно-зави-

симую справочную информацию об IDE или терминах, набираемых вами

в окне редактирования. Этот раздел знакомит вас со справочной

системой Borland Pascal for Windows.

Справочную систему Borland Pascal for Windows вы можете ис-

пользовать аналогично справочной системе Windows. Чтобы узнать о

работе Help Windows, выберите команду HelpіUsing Help. Вы узнаете

об общих средствах Help Windows (таких как аннотирование, исполь-

зование меток текста, просмотр и печать), о которых не упоминает-

ся в данном руководстве.

В следующих разделах описываются способы, с помощью которых

вы можете использовать справочную систему Borland Pascal for

Windows при разработке в IDE своих прикладных программ.

Чтобы больше узнать о справочнике Help, выберите команду

HelpіUsing Help или нажмите где-либо в справочной системе клавишу

F1.

Перемещение по справочной системе

Когда вы смотрите на экраны Help, то видите подчеркнутый

текст, цвет которого отличается от окружающего текста. Это ссыл-

ки. Ссылки могут представляться текстом, пиктограммами или графи-

кой, и вы можете выбирать их для получения более подробной инфор-

мации. Ссылки могут использоваться для вывода нового экрана Help,

представляющего новую информацию по отмеченной теме. Выбрать

ссылку можно следующими двумя способами:

* Щелкнув на ней кнопкой "мыши".

* Нажимая повторно клавиши Tab, пока ссылка не будет подсве-

чена, затем нажав клавишу Enter.

Новый справочный экран выводится с информацией по выбранной

теме: вы перешли на новое место в справочной системе. В этом эк-

ране вы можете видеть другие связи, которые вы можете выбрать для

вывода другой информации.

Чтобы вернуться к предыдущему справочному экрану, выберите

один из двух описанных ниже способов:

* Для возврата к последнему экрану выберите командную кнопку

Back.

* Чтобы увидеть список последних справочных экранов, выбери-

те командную кнопку History. Выберите из списка экран

Help, который вы хотите вывести.

Вы можете также видеть текст, подчеркнутый линией из точек,

цвет которого отличается от окружающего текста. Этот тип ссылки

вы можете использовать для вывода всплывающего окна с дальнейшей

информацией, воспользовавшись следующими способами:

* Щелкнув на ней кнопкой "мыши".

* Нажимая повторно клавиши Tab, пока ссылка не будет подсве-

чена, затем нажав клавишу Enter.

Выводится всплывающее окно, содержащее информацию по выбран-

ной теме. Оно остается на экране, пока вы не щелкните кнопкой

"мыши" или не нажмете клавишу Enter. Когда окно исчезнет, вы ос-

танетесь в том же месте справочной системы.

Запрос помощи

Получить доступ к справочной информации Help вы можете сле-

дующими способами:

* Щелкните "мышью" на команде Help полосы меню или для выво-

да меню Help нажмите клавиши Alt+H.

IDE выводит меню Help. В этом меню вы можете выбрать экран

Contents (Оглавление) системы Help, получить справку по

использованию справочной системы Help, вывести информацию

по теме, на которой позиционирован курсор в окне редакти-

рования, или вывести такую специфическую для Borland

Pascal информацию, как справка по языку, сообщениям об

ошибках Borland Pascal, примерах программ и т.д.

* Для вывода экрана оглавления справочной системы Borland

Pascal нажмите клавиши Shift+F1.

Экран оглавления Contents аналогичен оглавлению книги, но

вместо того, чтобы листать страницы, вы можете просто

щелкнуть "мышью" на подчеркнутой теме или нажать для пере-

хода к нужной теме клавишу Tab, а затем нажать клавишу

Enter.

* Нажмите клавишу F1.

- Если вы находитесь в окне редактирования, то экран Help

выводится со справочной информацией об использовании ре-

дактора. Чтобы увидеть детали, выберите одну из ссылок.

- Если выбрана команда меню, контекстно-зависимый экран

Help выводится с более подробной информацией об это эле-

менте меню.

* Выберите в диалоговом окне командную кнопку Help.

Выводится экран с кратким пояснением по всем командам,

доступным в данном диалоговом окне. Если вы щелкните

"мышью" на подчеркнутой теме или выберите ее помощью кла-

виатуры и нажмете Enter, то увидите более подробную инфор-

мацию о выбранной команде.

* Поместите курсор на термин в окне редактирования и выбери-

те Topic Search. Используйте любой из следующих методов:

- нажмите клавиши Ctrl+F1;

- выберите команду HelpіTopic Search;

- удерживая клавишу Ctrl, щелкните правой кнопкой "мыши"

(комбинация нажатий Ctrl+правая кнопка "мыши" должна

быть предварительно настроена - выберите команду

OptionsіEnviromentіMouse и выберите команду Topic

Search).

- выберите команду Topic Search в локальном меню окна ре-

дактирования.

Примечание: О локальных меню рассказывается в Главе 4.

Выводится справочный экран с информацией о ключевом слове,

на котором находится курсор в активном окне редактирова-

ния.

* В справочном окне Help выберите командную кнопку Search

(Поиск).

Выводится диалоговое окно поиска Search. В его верхнем

блоке списка вы можете прокручивать каждую тему в справоч-

ной системе Borland Pascal. Если вы знаете, какую тему вы

ищете, начните набирать эту тему в блоке ввода, и вы уви-

дите данную тему в блоке списка. Выделите тему и выберите

Show Topic.

Примечание: Если вы знаете, что нужно найти, то ко-

мандная кнопка Search дает вам скорейший способ для вывода

нужного экрана Help.

Если ваша тема имеет более детальное разбиение, вы увидите

в нижнем блоке списка другие темы. Выделите нужные темы и

выберите Go To. Выводится справочный экран по нужной теме.

* Выберите пиктограмму Help в оперативной полосе.

Выводится справочный экран Help.

Копирование примеров кода

Справочная система Help содержит пример кода для каждой про-

цедуры и функции. Вы можете скопировать эти примеры из справочной

системы в свое окно редактирования. Чтобы скопировать пример,

сделайте следующее:

1. Выведите экран Help по нужной процедуре или функции.

Вы увидите имя и пример исходного кода в нижней части ок-

на Help.

2. Для вывода примера щелкните кнопкой "мыши" на имени при-

мера кода.

3. Выберите команду EditіCopy.

Выводится диалоговое окно с примером кода. Вы можете вы-

делить часть кода для копирования в буфер вырезанного

изображения. Если вы этого не сделаете, пример будет ско-

пирован целиком.

4. Выберите команду Copy (Копирование).

5. Вернитесь в окно редактирования и выберите команду

EditіPaste, нажмите клавиши Shift+Ins или щелкните

"мышью" на командной кнопке Paste в буфере вырезанного

изображения или оперативной полосе.

Выход из справочной системы

Вы можете выбрать режим сохранения вывода экрана Help при

возврате в IDE или совсем закрыть основное окно Help.

* Для возврата в программу и сохранения фонового вывода те-

кущего окна Help щелкните "мышью" на окне, которое вы хо-

тите сделать активным. Когда вы захотите вывести окно Help

на переднем плане, щелкните на нем "мышью" - оно снова

станет активным.

* Чтобы закрыть основное окно Help и вернуться в прикладную

программу, выберите в меню окна Help команду FileіExit или

дважды щелкните "мышью" на его командной кнопке Cancel.

Запись и редактирование исходного кода

Поскольку редактор IDE ведет себя аналогично всем другим ре-

дакторам Windows, вероятно вы уже знаете, как редактировать

текст. В редакторе соблюдается стандарт общего доступа пользова-

теля CUA (Common User Access), который используется в большинстве

программ Windows. Те же команды редактирования, которые вы ис-

пользовали в других приложения Windows, работают также и в редак-

торе IDE. Полный перечень команд редактора вы найдете в Приложе-

нии A "Руководства программиста".

Примечание: Редактор позволяет вам открывать до 32

окон редактирования (что определяется доступной памятью).

Настройка конфигурации редактора

Для модификации поведения редактора Borland Pascal имеется

несколько параметров. Для вывода диалогового окна Editor выберите

команду OptionsіEnviromentіEditor.

Чтобы подробнее узнать о каждом параметре, выделите данный

параметр и нажмите клавишу F1. Справочная система Help поясняет,

что делает данный параметр.

Примечание: О выделении синтаксиса в редакторе расска-

зывается ниже.

Набор команд

Редактор IDE для Windows имеет два набора команд: набор ко-

манд CUA, при котором поведение редактора аналогично поведению

других редакторов Windows, и альтернативный набор команд, который

превращает редактор в редактор в стиле Borland. Кроме того, мно-

гие команды доступны в обоих наборах.

Примечание: Чтобы выбрать набор команд, обратитесь к

Приложению A "Справочного руководства программиста" или ис-

пользуйте справочник Help. Там вы найдете полный перечень

команд одного и другого набора.

При первоначальном запуске IDE для Windows редактор исполь-

зует набор команд CUA, который поддерживает все стандартные ко-

манды редактирования, общие для программ Windows, и многие из ко-

манд редактирования, знакомые тем, кто уже работал с языками и

программными продуктами Borland.

Чтобы использовать альтернативный набор команд, выберите ко-

манду OptionsіEnviromentіPreferences и параметр Alternate в груп-

пе Command Set.

Выбранный набор команд влияет не только на редактор. Напри-

мер, некоторые команды меню имеют оперативные клавиши, с помощью

которых вы можете выбирать команду, не прибегая к меню. В альтер-

нативном наборе команд F2 дает быстрый способ сохранения файла. В

наборе команд CUA оперативной клавиши для сохранения файла нет.

Использование редактора

В IDE для DOS и в IDE для Windows используется один редак-

тор. Если вы знаете, как работать с редактором в одной интегриро-

ванной среде, то сможете использовать его в другой. Чтобы узнать

об отмене ошибок, работе с блоками текста, поиске текста и огра-

ничителей и позиционировании курсора на строке с конкретным номе-

ром, см, соответствующие разделы предыдущей главы.

Редакторы для DOS и Windows имеют два небольших отличия:

* Редактор для Windows не имеет команды Find Text at Cursor.

* Редактор для Windows не имеет команды Block Insert Cursor,

которая назначает для курсора режима вставки форму прямоу-

гольника.

Выделение синтаксиса

IDE для Windows также обладает способностью выделения син-

таксиса. Как и в IDE для DOS вы можете выделять элементы исходно-

го кода цветом, но можете также изменять и атрибуты текста. Нап-

ример, не только изменить цвет элемента кода, но и сделать его

жирным, наклонным или подчеркнутым.

Для вывода диалогового окна Highlighting (Выделение) выбери-

те команду OptionsіEnviromentіHighlight.

ЙННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННН»

є=ЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫHighlightingЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫє

є і є

є Element±±±±±±±±±± Color±±±±±±±±±±±± Attribute±±±±±і є

є ЪДДДДДДДДДДДДДДДДїЪДДДДДДДДДДДДДДДДї±±±±±±±±±±±±±±і ЪДДДДДДДїє

є іWhitespace±±±±±±ііІFGІЫЫЫЫ °°°°і±< >±Normal±±±і і ы OK іє

є іComment±±±±±±±±±ііЫЫЫЫ °°°°ЫЫЫЫі±<*>±Bold±±±±±і АДДДДДДДЩє

є іЫReservedЫWordЫЫііІІІІЫЫЫЫ °°°°і±< >±Italic±±±і є

є іIdentifier±±±±±±ііЫЫЫЫ °°°°ЫЫЫЫіДДДДДДДДДДДДДДі є

є іSymbol±±±±±±±±±±ііІІІІЫЫЫЫ±±±±°°°°і±Ы±Underline±±і є

є іString±±±±±±±±±±ііЫЫЫЫ °°°°ЫЫЫЫі і є

є іNumber±±±±±±±±±±ііІІІІЫЫЫЫ °°°°і±±±±±±±±±±±±±±і є

є іAssembler±±±±±±±ііІІІІ±±±± °°°°і±Ы±Default±FG±і ЪДДДДДДДїє

є і±±±±±±±±±±±±±±±±ііЫЫЫЫ °°°°ЫЫЫЫі±ы±Default±BG±і іXCancelіє

є АДДДДДДДДДДДДДДДДЩАДДДДДДДДДДДДДДДДЩ±±±±±±±±±±±±±±і АДДДДДДДЩє

єЪїі є

єі {Syntax highlighting} іі є

єі Program Sample; іі є

єі uses WinCrt; іі є

єі var іі є

єі Number: integer; іі є

єі begin іі ЪДДДДДДДїє

єі Number := 123456; іі і ? Helpіє

єі Writeln['The number is',Number]; іі АДДДДДДДЩє

єі end. іі є

єАЩі є

ИНННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННј

Рис. 5.3 Диалоговое окно Highlighting.

             Element -  элемент;
Color  -  цвет;
Attribute  -  атрибут;

Whitespace - разделитель; Normal - обычный текст; Comment - ком-

ментарий; Bold - жирный; Reserved Word - зарезервированной слово;

Italic - наклонный; Identifier - идентификатор; Symbol - иденти-

фикатор; Underline - подчеркивание; String - строка; Number -

число; Assembler - код ассемблера; Default FG - основной цвет по

умолчанию: Default BG - фоновый цвет по умолчанию.

Цветовое выделение текста

Чтобы изменить цвет элемента, выполните следующие шаги:

1. В блоке списка Element выделите элемент, который нужно

изменить.

2. Выберите нужные цвета в матрице цветов Colors.

Текущий основной цвет отмечен буквами FG; текущий фоновый

цвет отмечен буквами BG. Если основной и фоновый цвета

совпадают, то в цветном квадрате выводится FB.

* Чтобы выбрать основной цвет с помощью "мыши", щелкните

на нем ее кнопкой. Чтобы выбрать цвет с помощью клавиа-

туры, используйте для перемещения по матрице цветов

клавиши стрелок, а когда будете находиться на нужном

цвете, нажмите F.

* Чтобы выбрать фоновый цвет с помощью "мыши", щелкните

на нем ее правой кнопкой. Чтобы выбрать цвет с помощью

клавиатуры, нажимайте клавишу Tab до выбора матрицы

Colors, затем используйте для перемещения по матрице

цветов клавиши стрелок, а когда будете находиться на

нужном цвете, нажмите B.

3. Выберите командную кнопку OK.

Использование системных цветов Windows

Приложения Windows используют одни и те же цвета фонового

цвета и цвета текста. Чтобы изменить системные цвета Windows, ис-

пользуйте контрольную панель администратора программ.

Вы можете выбрать системные цвета Windows в редакторе IDE.

Чтобы использовать для элемента основной системный цвет, выполни-

те следующие шаги:

1. В диалоговом окне Highlighting выделите элемент в блоке

списка Elements.

2. Выберите параметр Default FG.

Для назначения фонового цвета используются те же шаги, но

выбирается параметр Default BG.

Изменение атрибутов текста

Чтобы выбрать атрибут элемента выполните следующие шаги:

1. В диалоговом окне Highlighting выделите элемент в блоке

списка Element.

2. Выберите атрибут в параметрах Attributes.

Примечание: Чтобы текст стал жирным или наклонным, ре-

дактор должен использовать шрифт фиксированного размера.

Для изменения шрифтов используйте команду Optionsі

EnviromentіEditor и выберите нужный параметр Font.

Выбор атрибутов отразится в окне с примером кода.

Вы можете выбрать элемент для изменения, щелкнув "мышью" на

его вхождении в окне примера кода. Например, если вы щелкните

"мышью" на зарезервированном слове program, в блоке списка

Element выбирается элемент Reserved Word (Зарезервированное сло-

во).

Печать исходного кода

Если вы хотите получить печатную копию своего исходного ко-

да, выберите команду FileіPrint. IDE расширяет символы табуляции

(заменяя табуляцию соответствующим числом пробелов и затем печа-

тает ваш файл.

Выделение элементов синтаксиса при печати

Вы можете напечатать текст таким образом, чтобы синтаксичес-

кие элементы были выделены. Перед печатью вы должны пропустить

выводимый на принтер текст черед программу-фильтр PRNFLTR.EXE:

1. Выберите команду FileіPrinter Setup.

2. Выберите параметр Syntax Printing.

3. Выберите командную кнопку OK.

4. Для печати текста выберите команду FileіPrint.

Если параметр Syntax Highlight установлен, ваш текст пе-

чатается с выделением синтаксических элементов.

При установке в своей системе Windows вы, вероятно, устано-

вили один или более драйверов принтеров, с помощью которых можно

выполнять печать из Windows. Команда FileіPrinter Setup позволяет

вам выбрать нужный принтер и задать его для печати из IDE и для

конфигурации. Например, вы можете печатать на бумаги с разным

размером. Из IDE вы можете с помощью выбора кнопки Set Up в диа-

логовом окне Printed Setup задать свой принтер для печати.

Примечание: Подробности о конфигурировании принтера

Windows см. в "Руководстве пользователя по Microsoft

Windows"

Работа с файлами

При программировании в IDE вы можете создавать новые файлы,

открывать существующие файлы и сохранять их. Основные команды ра-

боты с файлами перечислены в следующей таблице:

Операции с файлами Таблица 5.1

ЪДДДДДДДДДДДДДДДДДДВДДДДДДДДДї

і Команда і Описание і

ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДґ

і FileіNew і Открывает новое окно редактиро-і

і і вания и присваивает ему временноеі

і і имя. і

ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДґ

і FileіOpen і Выводит диалоговое окно, с по-і

і і мощью которого можно открытьі

і і файл. і

ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДґ

і FileіSave і Сохраняет файл в активном окнеі

і і редактора на диске. і

ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДґ

і FileіSave As і Сохраняет файл в активном окнеі

і і редактора под другим именем. і

ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДґ

і FileіSave All і Сохраняет все модифицированныеі

і і файлы. і

АДДДДДДДДДДДДДДДДДДБДДДДДДДДДЩ

Открытие файлов

Чтобы открыть файл, выполните следующие шаги:

1. Выберите команду FileіOpen или командную кнопку open a

File оперативной полосы. Выводится диалоговое окно Open a

File (Открытие файла). Для задания открываемого файла вы

можете выполнить одно из следующих действий.

* В блоке ввода наберите полное имя файла.

* Наберите имя файла с трафаретными символами. Это от-

фильтровывает список файлов в соответствии с вашими

спецификациями. В списке Files выберите имя файла, ко-

торый вы хотите редактировать.

* Для вывода списка протокола (спецификаций имен файлов,

которые вы задавали ранее) щелкните "мышью" на символе

"стрелка вниз". Выберите требуемое имя файла или специ-

фикацию. Выбор спецификации файла выводит файлы, соот-

ветствующие данной спецификации.

* Дважды щелкнув "мышью" на имени другого каталога в

списке файлов, просмотрите содержимое этого каталога.

Выберите имя файла, который вы хотите редактировать.

2. Выберите командную кнопку OK.

Где находятся файлы?

Если это ваша первая попытка программирования под Windows,

вы можете не разобраться в том, где IDE ищет и сохраняет свои

файлы. IDE использует текущий рабочий каталог. Как определяется

текущий рабочий каталог, поясняется в следующем перечне:

* Если вы задаете основной файл, то каталог, в котором он

находится, становится текущим рабочим каталогом. При наи-

меновании файла вы можете указать полное имя маршрута.

Примечание: Подробнее об основных файлах рассказыва-

ется выше.

* Если вы не задаете основной файл, каталог, содержащий файл

в активном окне редактирования, становится текущим рабочим

каталогом. При сохранении файла в окне редактирования вы

можете указать полное имя маршрута.

* При отсутствии текущего окна редактирования текущим рабо-

чим каталогом становится каталог, в котором находится

BPW.EXE.

После открытия или создания файла Borland Pascal запоминает

его полный маршрут, даже если текущий рабочий каталог изменяется.

Поскольку текущий рабочий каталог обычно определяется основ-

ным файлом или файлом в активном окне редактирования, и эти эле-

менты сохраняются в файле конфигурации и файле оперативной облас-

ти, файл конфигурации и файл оперативной области неявно определя-

ют для проекта текущий рабочий каталог.

Примечание: Подробнее о рабочей операционной среде

рассказывается выше.

Работа с файлами в другом каталоге

Чтобы открыть файл в другом каталоге, выберите команду Fileі

Open и наберите в блоке ввода полное имя маршрута и имя файла.

Либо вы можете использовать для вывода файла в другом каталоге

список каталогов и выбор нужного файла. После того, как вы выбе-

рете имя файла и нажмете Enter, при следующем выборе команды

FileіOpen в том же сеансе вы увидите файлы в этом другом катало-

ге. Однако ваш текущий рабочий каталог не изменяется. Если вы

создали и сохранили новый файл, IDE сохраняет его в текущем рабо-

чем каталоге.

Если вы хотите работать с файлами в нескольких каталогах, то

можете использовать список протокола в диалоговом окне File Open.

Чтобы увидеть протокол, щелкните "мышью" на стрелке вниз справа

от блока ввода или нажмите клавиши Alt+"стрелка вниз"; в списке

может выводиться нужный вам файл.

Компиляция и выполнение

В IDE для Windows вы можете компилировать и выполнять прог-

раммы аналогично тому, как это делается в IDE для DOS. Об этом вы

можете прочитать в Главе 4. Стоит отметить следующее:

* Если ваша программа использует модуль WinCrt, когда прог-

рамма завершает выполнение, окно программы становится не-

активным. Чтобы продолжить работы в IDE, закройте его.

Чтобы пользователю не нужно было закрывать окно WinCrt,

используйте процедуру DoneWinCrt. Прочитайте о DoneWinCrt

в Главе 1 "Справочного руководства программиста".

* Если в программе, использующей модуль WinCrt, во время ее

выполнения происходит ошибка, окно, в котором работает

программа, становится неактивным перед ее завершением.

Чтобы посмотреть, что произошло, закройте окно программы.

Тогда вы увидите информационное окно, в котором выводится

номер ошибки и адрес, на котором она произошла.

Просмотр исходного кода

IDE для Windows содержит новое программное инструментальное

средство просмотра объектов - ObjectBrowser. Оно позволяет вам

исследовать программы и модули в программах и многое другое. Даже

если разрабатываемое вами приложение не использует объектно-ори-

ентированное программирование, вы найдете ObjectBrowser чрезвы-

чайно полезным средством. Вы можете просматривать иерархию объек-

тов, модулей и всех процедур, функций, переменных, типов, конс-

тант и другие используемые в программе идентификаторы. С помощью

ObjectBrowser вы можете делать следующее:

* Просмотреть в графическом виде в своей прикладной програм-

ме иерархию объектов, затем выбрать объект и просмотреть

все его процедуры, функции и другие содержащиеся в прог-

рамме идентификаторы.

* Вывести список всех глобальных идентификаторов, используе-

мые в вашей программе, и увидеть их описания, вывести все

ссылки на них в своей программе или перейти туда, где они

описываются в исходном коде.

* Вывести список всех используемых в программе модулей, за-

тем выбрать один из них и просмотреть список всех иденти-

фикаторов его интерфейсной части. В этом списке вы можете

выбрать идентификатор и просмотреть его, как любой другой

идентификатор своей программы.

* Выбрать идентификатор в исходном коде, затем просмотреть

детальную информацию по нему, щелкнув на этом идентифика-

торе правой кнопкой "мыши".

Перед использованием ObjectBrowser убедитесь, что в диалого-

вом окне OptionsіCompiler установлены следующие параметры:

* Debug Information (Информация для отладки).

* Locals Symbols (Локальные идентификаторы).

* Symbol Information (Информация об идентификаторах).

Для активизации ObjectBrowser выберите в меню Search (Поиск)

команду Objects (Объекты), Units (Модули) или Globals (Глобальные

идентификаторы). Если программа находится в текущем окне, или ос-

новной файл еще не скомпилирован, то перед выводом окна просмотра

IDE компилирует вашу программу.

Если программа будет успешно скомпилирована, сформирована

или построена, вы можете внести в исходный код некоторые измене-

ния, а если следующая компиляция завершиться неудачно, то вы все

равно сможете просматривать свою программу в том виде, как вышли

из нее при последней успешной компиляции. Чтобы это происходило,

должен быть установлен параметр Preserve Symbols (он установлен

по умолчанию). Данный параметр можно найти в диалоговом окне

OptionsіEnviromentіStartup. Поскольку Preserve Symbols - это па-

раметр запуска, изменение его установки не будет иметь действие,

пока вы не выйдите из IDE и не запустите ее снова.

Если у вас есть "мышь", то исходный код удобнее просматри-

вать, если задать активизацию ObjectBrowser правой кнопкой "мы-

ши". Затем, удерживая нажатой клавишу Ctrl, вы можете использо-

вать правую кнопку "мыши" для указания и проверки объекта, проце-

дуры, функции, переменной или другого идентификатора в вашем ис-

ходном коде и его анализа (вывода детальной информации).

Примечание: Для быстрого просмотра идентификатора, на

котором в исходном коде позиционирован курсор, вы можете

также выбрать в локальном меню окна редактирования команду

Browse Symbol at Cursor (Просмотр идентификатора в позиции

курсора).

Чтобы задать просмотр с помощью "мыши", выполните следующие

шаги:

1. Выберите команду OptionsіEnviromentіMouse.

2. Выберите параметр Browse as the Ctrl + Right Mouse Button

(Просмотр по клавише Ctrl + правая кнопка "мыши").

3. Выберите командную кнопку OK.

В верхней части окна ObjectWindows находится оперативная по-

лоса ObjectBrowser. Вы можете выбирать любую командную кнопку

оперативной полосы, щелкая на ней кнопкой "мыши" или используя

оперативную клавишу. Выбрав кнопку или соответствующую оператив-

ную клавишу, вы указываете ObjectBrowser на выполнение некоторого

действия. Вы будете видеть следующие командные кнопки, их клавиа-

турные эквиваленты и соответствующие действия:

ЪДДДДДДДДДДДї

і і

і і

і і

АДДДДДДДДДДДЩ

F1 Help (Вывод справочной информации)

ЪДДДДДДДДДДДї

і і

і і

і і

АДДДДДДДДДДДЩ

Ctrl+G Go to (Переход на исходный код для выбранного

элемента)

ЪДДДДДДДДДДДї

і і

і і

і і

АДДДДДДДДДДДЩ

Ctrl+B Browse (Просмотр детальной информации по выб-

ранному элементу)

ЪДДДДДДДДДДДї

і і

і і

і і

АДДДДДДДДДДДЩ

Ctrl+V View (Вывод предыдущего окна просмотра):

ЪДДДДДДДДДДДї

і і

і і

і і

АДДДДДДДДДДДЩ

Ctrl+O Display (Вывод иерархии объектов)

ЪДДДДДДДДДДДї

і і

і і

і і

АДДДДДДДДДДДЩ

Ctrl+R List (Перечень всех ссылок на идентификатор)

ЪДДДДДДДДДДДї

і і

і і

і і

АДДДДДДДДДДДЩ

Ctrl+P Print (Печать иерархии объектов)

ЪДДДДДДДДДДДї

і і

і і

і і

АДДДДДДДДДДДЩ

Ctrl+W Replace (Замена текущего окна просмотра)

ЪДДДДДДДДДДДї

і і

і і

і і

АДДДДДДДДДДДЩ

Ctr+W Open (Открытие нового окна просмотра)

Рис. 5.4 Командные кнопки оперативной полосы ObjectBrowser.

Примечание: От того, с каким именно окном

ObjectBrowser вы работаете, зависит, какие в точности кноп-

ки выводятся в оперативной полосе.

Последние две кнопки показывают в действительности два раз-

личных представления одной кнопки. При первом использовании

ObjectBrowser вы увидите командную кнопку одиночного окна. Щелк-

ните на ней "мышью", и вы увидите кнопку множественных окон.

Когда вы выбираете кнопку одиночного окна и начинаете прос-

мотр, новое окно просмотра при каждом действии просмотра заменяет

текущее окно просмотра. При выборе кнопки множественных окон окна

остаются на экране, пока вы их не закроете.

Вы можете быстро изменить действие этих кнопок на обратное:

удерживая нажатой кнопку Shift, выберите следующее действие прос-

мотра. Например, если выводится кнопка множественных окон, то при

нажатии клавиши Shift следующее окно просмотра будет замещать те-

кущее.

Просмотр объектов

ObjectBrowser позволяет вам увидеть "общий план" иерархии

объектов, а также мелкие детали. Чтобы активизировать

ObjectBrowser и графически показать на экране объекты, выберите

команду SearchіObject. ObjectBrowser рисует ваш объект и показы-

вает в виде горизонтального дерева его соотношения "предок-пото-

мок". Красные линии в иерархии помогают вам ясно увидеть непос-

редственные отношения "предок-потомок" текущего объекта.

ЙННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННН»

є = і ? і О і П і * і Ы іЫЫЫЫЫЫЫЫЫBrowsing ObjectsЫЫЫЫЫЫЫЫЫЫіvі^є

єДДДБДДДБДДДБДДДБДДДБДДДБДДДДДДДДДДБДБДє

є і ^

є Ъґ±TWindowsObject±ГВґ±TWindow±ГДБДВВВґ±TMDIClient±іЫ

є і і ііі ±

є і і ііАґ±TListBox±Гґ±±

є і і іі ±

є і і іАДґ±TGroupBox±ГД±

є і і і ±

є і і АДДґ±TButton±Гґ±T±

єі±TObject±±ГЕВВї і ±

є іііі Аґ±TDialog±Гґ±TDglWindow±і ±

є іііі ±

є іііАґ±TStream±ГВґ±TEmsStream±і ±

є ііі і ±

є ііі Аґ±TDosStream±ГДґ±TBufSteram±і ±

є ііі ±

є ііАДґ±TScroller±і ±

є іі ±

є іАДДґ±TCollection±Гґ±TSortedCollection±ГВґ±TStringC±

є і і ±

є і Аґ±TStrColl±

є АДДДґЫApplicationЫГґ±THelloApp±і ±

є v

И<±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±>±

Рис. 5.5 Просмотр иерархии объектов прикладной программы.

Чтобы увидеть более подробную информацию о конкретном объек-

те, дважды щелкните на нем кнопкой "мыши". Если вы не используете

"мышь", выберите объект с помощью клавиш управления курсором

(стрелок) и нажмите Enter. ObjectBrowser перечисляет используемые

в объекте символы (процедуры, функции, переменные и т.д.)

ЙННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННН»

є = і ? і О і П і * і Ы іЫЫЫЫЫЫЫЫЫBrowsing TApplicationЫЫЫЫЫіvі^є

єДДДБДДДБДДДБДДДБДДДБДДДБДДДДДДДДДДБДБДє

є є

є Browsing TApplication є

є ЪДДДДДДДДДДї є

є іv±±±±±±Status:Integer±±±±±±±±±±±±±^і є

є іv Name:PChar ±і є

є іv MainWindow:PWindowsObject ±і є

є ЪДДДДДДДї іv HAccTable:Word ±і ЪДДДДДДДДДДї є

є іTObjectГДґv KBHandleWnd:PWindowsObject ±ГДґTHelloApplі є

є АДДДДДДДЩ іp Init[PChar] ±і АДДДДДДДДДДЩ є

є іp ы Done ±і є

є іf ы IdleAction:Boolean ±і є

є іp ы InitApplication vі є

є і<Ы±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±>±і є

є АДДДДДДДДДДЩ є

є є

є Filters: ы F P V і p v є

є X і і і є і і є

є є

ИНННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННј

Рис. 5.6 Просмотр детальной информации по объекту.

Слева от каждого идентификатора объекта выводятся одна или

более букв. Символ описывает вид идентификатора.

Буквенные символы в ObjectBrowser

Таблица 5.2

ЪДДДДДДДДДДДДВДДДї

і Буква і Функция і

ГДДДДДДДДДДДДЕДДДґ

і F і Функция і

і P і Процедура і

і T і Тип і

і V і Переменная і

і C і Константа і

і L і Метка і

і I і Наследование от предка і

і p і Приватный идентификатор і

і v і Виртуальный идентификатор і

АДДДДДДДДДДДДБДДДЩ

Фильтры

Те же символы, что идентифицируют вид идентификатора, выво-

дятся в матрице фильтров Filters в нижней части окна

ObjectBrowser. Вы можете использовать фильтры для выбора типа

идентификаторов, список которых хотите видеть.

Матрица фильтров содержит столбец для каждой буквы; буква

может выводиться в верхней или нижней строке.

Примечание: Для выбора типа идентификаторов вы можете

также использовать окно Browser Options. Выберите команду

OptionsіBrowser и идентификаторы, которые вы хотите вывести

в списке.

Чтобы просмотреть все экземпляры символа конкретного типа,

щелкните "мышью" на верхней ячейке столбца буквы. Например, чтобы

просмотреть все переменные в текущем выбранном объекте, щелкните

на верхней ячейке столбца V. Выводятся все переменные, используе-

мые в объекте.

Чтобы скрыть все экземпляры конкретного объекта или иденти-

фикатора, щелкните "мышью" на нижней ячейке столбца буквы. Напри-

мер, чтобы просмотреть только функции или процедуры объекта, вам

нужно сделать скрытыми все переменные. Щелкните "мышью" на нижней

ячейке в столбце V, и на верхних ячейках в столбцах F и P.

Примечание: Вы можете изменить несколько установок

фильтра сразу. Буксируйте "мышь" по ячейкам, которые вы хо-

тите выбрать в матрице Filters.

В некоторых случаях для идентификатора выводится более одной

буквы. Второй буквенный символ выводится непосредственно после

первой буквы, обозначающей тип идентификатора и служит для даль-

нейшего описания идентификатора:

* I обозначает наследуемый идентификатор;

* p обозначает приватный идентификатор;

* v обозначает виртуальный идентификатор.

Просмотр описаний перечисленных идентификаторов

Для просмотра описания конкретного содержащегося в списке

идентификатора используйте следующие методы:

* дважды щелкните на идентификаторе кнопкой "мыши";

* выберите идентификатор и щелкните "мышью" на кнопке Browse

или нажмите Ctrl+B;

* выберите идентификатор и нажмите клавишу Enter.

При просмотре в режиме одного окна (кнопка Window оператив-

ной полосы выводит на экран только одно окно), если вы хотите

вернуться на уровень выше, щелкните "мышью" на кнопке вывода пре-

дыдущего окна просмотра или нажмите клавиши Ctrl+V.

Хотя очень легко использовать оперативную полосу для выбора

одно- и многооконного режима, тоже самое вы можете делать с по-

мощью меню и диалогового окна. Чтобы новое окно просмотра заменя-

ло текущее, сделайте следующее:

1. Выберите команду OptionsіBrowser.

2. Установите параметр Replace Current sub-browsing.

3. Выберите командную кнопку OK.

Чтобы новое окно просмотра при выборе перечисленного в спис-

ке идентификатора оставалось на экране, сделайте следующее:

1. Выберите команду OptionsіBrowser.

2. Установите параметр New Browser sub-browsing.

3. Выберите командную кнопку OK.

Просмотр глобальных идентификаторов

С помощью ObjectBrowser вы можете просматривать все модули,

которые использует программа. Чтобы открыть окно со списком всех

используемых в программе модулей и именем самой прикладной прог-

раммы выберите команду SearchіUnits.

Выберите модуль, о котором вам нужно получить более подроб-

ную информацию. Как и в случае глобальных идентификаторов, вы мо-

жете выполнять поиск в списке модулей, набирая первые несколько

букв имени модуля в блоке ввода Search в нижней части окна.

После выбора модуля вы можете перечислить вывести список

всех идентификаторов в интерфейсной части модуля.

* В выводимом списке модулей дважды щелкните "мышью" на име-

ни модуля, выделите имя модуля и выберите Inspect или вы-

делите имя и нажмите клавишу Enter.

В этом списке вы можете выделить идентификатор и сделать

следующее:

- Чтобы увидеть описание идентификатора, дважды щелкните

на идентификаторе кнопкой "мыши", выделите его и выбери-

те командную кнопку Inspect (Проверка), или выделите его

и нажмите клавишу Enter.

- Чтобы перейти на строку исходного кода, где описывается

идентификатор, выберите командную кнопку Go To Source

Code.

- Чтобы вывести список всех ссылок на идентификаторы, вы-

берите командную кнопку Reference. Если вы выберите одну

из этих ссылок, ObjectBrowser позиционирует ваш курсор в

исходном коде.

* Чтобы перейти на описание идентификатора в исходном коде,

выберите командную кнопку Go to Source Code.

* Чтобы перечислить все ссылки на идентификатор в вашем при-

ложении, выберите командную кнопку Reference.

Просмотр идентификаторов в исходном коде

Вы можете просматривать идентификаторы в своем исходном ко-

де, не выводя сначала иерархию объектов или список идентификато-

ров. Выберите один из следующих методов:

* Подсветите идентификатор в своем коде и выберите команду

SearchіSymbol.

* Если ваша "мышь" настроена для просмотра, удерживая нажа-

той клавишу Ctrl, щелкните на идентификаторе в вашем коде

правой кнопкой "мыши".

* Для вывода локального меню окна редактирования нажмите

клавиши Alt+F10 или щелкните правой кнопки "мыши" и выбе-

рите команду Browse Symbol at Cursor.

Если выделенный вами идентификатор представляет собой струк-

турный тип, то ObjectBrowser выводит для этого типа информацию

обо всех идентификаторов в его области действия. Любой из них вы

можете выбрать для дальнейшей проверки. Например, если вы выбери-

те объектный тип, то увидите список всех идентификаторов в облас-

ти действия этого объекта.

Выполнение в IDE других программ

В IDE вы можете запускать по вашему выбору четыре других

программы: отладчик Turbo Debugger, пакет разработчика ресурсов

Resource Workshop, утилиту WinSight и профилировщик Turbo

Profiler. Чтобы запустить любую из этих программ, выберите коман-

ду Tools для открытия меню Tools и затем выберите инструменталь-

ное средство, которое вы хотите запустить. Чтобы изменить маршрут

или передать этим программам аргументы, используйте диалоговое

окно Tools (OptionsіTools).

В отличие от IDE для DOS вы не можете добавить в меню Tools

другие утилиты. Так как IDE для Windows представляет собой прик-

ладную программу Windows, на самом деле это не дает преимуществ.

Вы всегда можете переключиться на другую программу, используя

средства переключения задач Windows.

Настройка конфигурации IDE

Вы можете настраивать конфигурацию IDE, сохранять свою опе-

рационную среду и управлять проектами аналогично тому, как это

делается в IDE для DOS (см. выше). При сохранении операционной

среды и управлении проектами между IDE для DOS и IDE для Windows

существуют следующие различия:

* IDE для Windows всегда сохраняет файл оперативной области

в том же каталоге, что и текущий файл конфигурации. Вы не

можете переопределить это, как в IDE для DOS.

* Чтобы очистить основной файл, выберите в IDE для Windows

команду CompileіClear Primary File. Вы можете использовать

этот метод также и в IDE для DOS, но у вас есть возмож-

ность выбора в диалоговом окне Primary File командной

кнопки Clear Primary File.


Глава 6. Отладка в интегрированной среде

Интегрированная интерактивная среда разработки программ

Borland Pascal (IDE) включает в себя ряд средств, облегчающих

разработку программ: автоматическое управление проектами, средств

обеспечения модульной структуры программы, быструю компиляцию и

простые в использовании оверлеи. Но несмотря на все это ваша

программа все равно может содержать ошибки, что не позволит ей

корректно работать.

IDE для DOS Borland Pascal предоставляет вам инструменталь-

ные средства для отладки программ, то есть поиска и исправления

ошибок. В этой главе описываются инструментальные средства и про-

цедуры отладки программы в интегрированной среде, включая следую-

щие темы:

* обзор ошибок и методов отладки;

* управление выполнением программы;

* проверка значений;

* остановки выполнения программы.

Данная глава посвящена встроенному отладчику IDE для DOS.

Все описанные процедуры применимы также к Турбо отладчику (Turbo

Debugger) и Турбо отладчику для Windows, хотя имена меню и нажи-

маемые клавиши в них могут отличаться.

Что такое отладка?

Отладка - это процесс поиска и исправления ошибок в програм-

ме, препятствующих корректной работе программы. Перед тем как уг-

лубиться в специфические средства IDE Borland Pascal, которые по-

могают при отладке, дадим краткое описание видов ошибок, которые

вы можете наблюдать, и различного рода операций, которые вы будет

использовать для их поиска.

Какие существуют виды ошибок?

Существует три основных типа ошибок: ошибки этапа компиля-

ции, ошибки этапа выполнения и логические ошибки. Если вы уже хо-

рошо знакомы с этими понятиями, то можете пропустить следующий

раздел до методов отладки.

Ошибки этапа компиляции

Ошибки этапа компиляции или синтаксические ошибки происхо-

дят, когда ваш исходный код нарушает правила синтаксиса Паскаля.

Borland Pascal на может скомпилировать вашу программу, пока она

не будет содержать допустимые операторы Паскаля. Когда компилятор

встречает оператор, который он не может распознать, соответствую-

щий файл выводится в окне редактирования, курсор позиционируется

на то место, которое не понял компилятор, и выводится сообщение

об ошибке.

Компилятор, работающий в режиме командной строки, также дает

вам некоторую информацию. Когда он находит синтаксическую ошибку,

то выводит содержащую ошибку строку с номером этой строки и сооб-

щением об ошибке.

Наиболее общей причиной ошибок этапа компиляции являются

ошибки набора (опечатки), пропущенные точки с запятой, ссылки на

неописанные переменные, передача неверного числа (или типа) пара-

метров процедуры или функции и присваивание переменной значений

неверного типа.

После исправления ошибки вы можете выполнить компиляцию за-

ново. После устранения в программе всех синтаксических ошибок и

ее успешной компиляции программа будет готова к выполнению и по-

иску ошибок этапа выполнения и логических ошибок.

Ошибки этапа выполнения

Ошибки этапа выполнения или семантические ошибки происходят,

когда вы компилируете полную программу, которая при ее выполнении

делает что-то недопустимое. То есть, программа содержит допусти-

мые операторы Паскаля, но при выполнении операторов что-то проис-

ходит неверно. Например, ваша программа может пытаться открыть

для ввода несуществующий файл или выполнить деление на ноль.

Когда программа Borland Pascal обнаруживает такую ошибку,

она завершает выполнение и выводит сообщение следующего вида:

Run-time error ## at seg:ofs

Если вы выполняете программу из IDE, Borland Pascal автома-

тически находит вызвавший ошибку оператор (как в случае синтакси-

ческих ошибок). Если вы выполняете программу вне IDE, то вы може-

те запустить IDE и, чтобы найти вызвавший ошибку оператор, ис-

пользовать команду SearchіFind Error, которая дает вам адрес сег-

мента и смещения (seg:ofs). Если вы используете компилятор ко-

мандной строки, то можете для поиска ошибки использовать параметр

/F.

Логические ошибки

Логические ошибки - это ошибки проектирования и реализации

программы. То есть, ваши операторы допустимы и что-то делают, но

не то, что вы предполагали. Эти ошибки часто трудно отследить,

поскольку IDE не может найти их автоматически, как синтаксические

и семантические ошибки. К счастью, IDE включает в себя средства

отладки, помогающие вам найти логические ошибки.

Логические ошибки приводят к некорректному или непредвиден-

ному значению переменных, неправильному виду графических изобра-

жений или невыполнению кода, когда это ожидается. В остальной

части этой главы обсуждаются методы отслеживания этих логических

ошибок.

Методы отладки

Иногда, когда программа делает что-то непредвиденная, причи-

на достаточно очевидна, и вы можете быстро исправить код програм-

мы. Но другие ошибки более трудноуловимы и вызываются взаимодейс-

твие различных частей программы. В этих случаях лучше всего оста-

новить вашу программу в заданной точке, пройти ее шаг за шагом и

просмотреть состояние переменных и выражений. Такое управляемое

выполнение - ключевой элемент отладки.

В данном разделе описываются различные возможности отладки в

IDE для DOS Borland Pascal.

Выполнение по шагам и трассировка

Команды выполнения по шагам Step Over и трассировки Trace

Into меню выполнения Run дают вам возможность построчного выпол-

нения программы. Единственное отличие выполнения по шагам и трас-

сировки состоит в том, как они работают с вызовами процедур и

функций. Выполнение по шагам вызова процедуры или функции интерп-

ретирует вызов как простой оператор и после завершения подпрог-

раммы возвращает управление на следующую строку. Трассировка

подпрограммы загружает код этой подпрограммы и продолжает ее

построчное выполнение.

Остановка выполнения

Существует два способа сообщить IDE, что программу нужно вы-

полнить до определенной точки, а затем остановить. Первый и прос-

тейший способ состоит в том, чтобы найти позицию в программе, где

вы хотите остановиться, затем выбрать в меню Run команду Go to

Cursor (Выполнение до позиции курсора). Ваша программа выполняет-

ся как обычно, пока не достигнет оператора, где она должна оста-

новиться. В этой точке вы можете проверить значения и продолжать

выполнение непрерывно или по шагам.

Второй способ состоит в том, чтобы остановить в определенной

заданной точке вашу программу. Эта точка называется точкой оста-

нова. Когда вы выполняете программу, она останавливается перед

выполнением оператора в точке останова. Точки останова - это бо-

лее гибкий механизм, чем использование метода выполнения до пози-

ции курсора (Go to Cursor), поскольку в программе вы можете уста-

новить несколько точек останова.

Отслеживание и модификация

При выполнении программы по шагам вы можете наблюдать ее вы-

вод несколькими способами. Первый состоит в переключении в случае

необходимости экранов. При втором способе используется второй мо-

нитор. В-третьих, для вывода программы вы можете открыть окно в

IDE для DOS.

Кроме того, чтобы показать вывод программы, встроенный от-

ладчик позволяет вам просматривать значения переменных, выражений

и структур данных. С помощью команды Wathes в меню Debug в окне

просмотра Watches вы можете добавлять или удалять отслеживаемые

элементы. В этом диалоговом окне вы можете проверять переменные и

выражения и изменять значения любых переменных, включая строки,

указатели, элементы массива и поля записей, что позволяет вам

проверять реакцию программы на различные условия.

Поиск

Если вам нужно найти в программе описания процедуры или

функции, либо определения объекта, это легко можно сделать с по-

мощью средства просмотра объектов ObjectBrowser. С помощью меню

Search и выбора команд Objects, Globals, Units или Symbols выбе-

рите соответствующее окно просмотра. См. Главу 4 ("Программирова-

ние в интегрированной среде для DOS"), где о просмотре кода расс-

казывается более подробно.

Генерация отладочной информации

Перед отладкой программы вам нужно указать компьютеру, что

нужно сообщить компилятору на необходимость генерации некоторой

дополнительной информации, благодаря которой он сможет отслежи-

вать, какие строки исходного кода соответствуют отдельным частям

выполняемой программы. Эта дополнительная информация называется

отладочной информацией. Вы можете включить эту информации, выбрав

соответствующий параметр (кнопку с независимой фиксацией)

диалогового окна Compiler Options интегрированной среды (команда

OptionsіCompiler) или включив в код программы соответствующую ди-

рективу компилятора.

Когда вы компилируете программу Borland Pascal, компилятор

всегда сохраняет список используемых идентификаторов, который на-

зывается таблицей идентификаторов. В этом списке отслеживаются

имена всех переменных, констант, типов, процедур и функций. Для

целей отладки там сохраняются также номера строк исходных файлов,

где встречаются все эти идентификаторы. Выбрав в диалоговом окне

Compiler Options параметр Debug Information (Отладочная информа-

ция) или задав директиву компилятора $D+, вы указываете компиля-

тору, что в таблицу идентификаторов нужно добавить информацию о

номерах строк.

Встроенная и автономная отладка

В диалоговом окне параметров отладчика Debugger Options

(OptionsіDebugger) вы можете сообщить компилятору, нужно ли гене-

рировать отладочную информацию для использования встроенного или

автономного отладчика (такого как Turbo Debugger), или для обоих.

Если вы хотите использовать встроенный отладчик, то нужно выбрать

параметр Integrated (который устанавливается по умолчанию).

Информация в модулях

Если вы пишете большую программу, которая использует модули,

и отладочная информация получается слишком объемной, вы можете

сократить объем этой информации для отдельных модулей, используя

в них директиву компилятора $L- или отменив в диалоговом окне

Compiler Options параметр Local Symbols (Информация о локальных

идентификаторах).

Если вы выключите для модуля генерацию информации о локаль-

ных идентификаторах, то из отладочной информации для этого модуля

исключаются все идентификаторы, описанные в секции реализации мо-

дуля. Для всех идентификаторов в интерфейсной секции будет гене-

рироваться информацию для всех идентификаторов, так что вы сможе-

те использовать средства отладки.

Управление выполнением

Основной смысл использования встроенного отладчика состоит в

управляемом выполнении. Отслеживая выполнение каждой инструкции,

вы можете легко определить, какая часть вашей программы вызывает

проблемы. В отладчике предусмотрено пять основных механизмов уп-

равления выполнением программы, которые позволяют вам:

- выполнять инструкции по шагам;

- трассировать инструкции;

- выполнять программу до заданной точки;

- находить определенную точку;

- выполнять сброс программы.

Само по себе выполнение программы по шагам может быть недос-

таточно полезным, разве что поможет найти то место, где что-то

происходит совершенно неверно. Но управляемое выполнение дает вам

возможность проверять состояние программы и ее данных, например,

отслеживать вывод программы и ее переменные, как описывается в

данной главе.

Что такое шаг?

Когда вы отлаживаете программу, наименьшим выполняемым эле-

ментом является строка. Этот означает, что вы можете управлять

отладкой до уровня отдельной строки исходного кода программы. По-

этому, если на одной строке программы содержится несколько опера-

торов Паскаля, вы не сможете отладить эти операторы индивидуаль-

но. С другой стороны, с целью отладки вы можете разбить оператор

на несколько строк, которые будут выполняться за один шаг.

Все выполнение в отладчике, включая выполнение по шагам,

трассировку и останов, основывается на строках. Подсвечивая стро-

ку, встроенный отладчик всегда сообщает вам, какую строку вы вы-

полняете следующей (строка выполнения). Строка выполнения выво-

дится цветом, отличным от нормального цвета. Благодаря этому вы

можете легко видеть, где находитесь.

Выполнение программы по шагам

Выполнение по шагам - это простейший способ выполнения прог-

раммы по элементарным фрагментам. Выбор команды RunіStep Over или

нажатие клавиши F8 вызывает выполнение отладчиком всего кода в

операторе, указанном строкой выполнения, включая любые вызываемые

на ней процедуры или функции, пока управление не вернется обратно

к вам. После этого строка выполнения указывает следующий выполня-

емый оператор.

Возьмем, например, следующий пример программы:

program StepTest;

function Negate(X: Integer): Integer;

begin

Negate := -X;

end;

var

I: Integer;

begin

for I := 1 to 10 do Writeln(Negate(I));

end.

Пример 6.1 Простая программа, выполняемая по шагам.

Если в окне редактирования вы выведите StepTest и нажмете

клавишу F8, то строка выполнения перемещается на оператор begin в

начале основного цикла, поскольку это первое, что выполняется в

программе. Второе нажатие клавиши F8 выполняет begin и перемещает

строку выполнения вниз до оператора for на следующей строке. Пос-

ле этого нажатие F8 вызывает выполнение всего цикла for; на экран

пользователя выводятся числа от -1 до -10, а строка выполнения

перемещается к end.

Хотя функция Negate вызывается 10 раз, строка выполнения ни-

когда на нее не перемещается. Выполнение по шагам позволяет от-

ладчику не показывать детали любых вызовов для отдельной строки.

Выполнение по шагам вызывает выполнение всего цикла for сразу,

поэтому вы не сможете видеть изменения в ходе выполнения цикла.

Если вы хотите видеть подробности цикла, внесите в пример следую-

щее простое изменение.

begin

for I := 1 to 10 do

Writeln(Negate(I));

end.

Пример 6.2 Изменение формата кода для лучшего выполнения по

шагам.

Поскольку оператор Паскаля может занимать несколько строк,

такая программа будет в точности эквивалентна предыдущей версии,

а генерируемый код будет идентичен. Но поскольку оператор Writeln

теперь находится на отдельной строке, отладчик может интерпрети-

ровать его отдельно. Если теперь вы будете нажимать клавишу F8,

то увидите, что строка выполнения будет при выполнении цикла 10

раз возвращаться на Writeln.

Трассировка программы

Трассировка программы во многом аналогичная ее выполнению по

шагам. Единственное исключение состоит в том, что когда встреча-

ется оператор вызова процедуры или функции, при трассировке эти

процедуры и функции также выполняются по шагам, а при простом вы-

полнении по шагам управление возвращается вам после завершения

выполнения подпрограммы.

Например, чтобы выполнить трассировку кода в Примере 6.1,

загрузите файл, затем выберите команду RunіTrace Into или нажмите

клавишу F7. Когда вы в первый раз делаете это, управление переме-

щается на оператор begin основной программы. Повторное нажатие F7

снова перемещает строку управления на оператор for. После этого

нажатие клавиши F7 трассирует вызов функции Negate - строка вы-

полнения перемещается на оператор begin в блоке функции. Если вы

продолжаете нажимать F7, строка выполнения перемещается по функ-

ции, а затем, когда вы дойдете до оператора end, возвращается к

оператору вызова.

Формат вашей программы влияет на поведение строки выполнения

при трассировке, хотя и не в такой степени как при пошаговом вы-

полнении. Если код сформатирован как в Примере 6.1, то трассиров-

ка оператора for приводит к выполнению 10 раз функции Negate. Ес-

ли вы разобъете оператор for на две строки, как в Примере 6.2, то

трассировка оператора end функции возвращает строку выполнения ту

строку основной программы, которая будет выполняться следующей.

Первые девять раз это снова будет вызов функции. В десятый раз

строка выполнения перемещается на оператор end программы.

Трассировка или выполнение по шагам?

Пошаговое выполнение или трассировка выполняет одно и то же

действие, кроме того случая, когда строка выполнения находится

под строкой вызова процедуры или функции, или когда вы выполняете

оператор begin в начале программы или модуля, который использует

другие модули.

Выполнение begin в блоке begin..end основной программы вызы-

вает код инициализации для любого используемого в программе моду-

ля в том порядке, который указывается в операторе uses программы.

Аналогично, выполнение оператора begin в начале секции инициали-

зации вызывает код инициализации для любых модулей, используемых

в данном модуле. Выполнение по шагам и трассировка работает в

этих случаях как и можно ожидать - пошаговое выполнение begin вы-

полняет всю инициализацию, возвращая управление на следующий опе-

ратор только после того, как все будет завершено; при трассировке

выполняется трассировка кода инициализации.

Примечание: О модулях и их секциях инициализации расс-

казывается в Главе 7 "Модули Borland Pascal".

Пошаговое выполнение и трассировка методов объектов

Если вы используете в своей программе объекты, отладчик ин-

терпретирует свои методы аналогично тому, как он интерпретирует

обычные процедуры и функции. Пошаговое выполнение метода интерп-

ретирует метод как один шаг, возвращая управление к отладчику

после того как метод завершает выполнение. Трассировка метода

загружает и выводит на экран код метода и трассирует его операто-

ры.

Пошаговое выполнение и трассировка внешнего кода

Если вы выполняете в программе компоновку с внешним кодом,

используя для этого директиву компилятора {$L имя_файла}, то если

компонуемый файл .OBJ содержит отладочную информацию, вы можете

трассировать этот код или выполнять его по шагам. Borland Pascal

ничего не знает об отлаживаемом вами коде в этих модулях, но он

будет показывать вам соответствующие строки в исходном коде.

Примечание: Требования к внешнему коду поясняются в

Главе 25 "Руководства по языку".

Вы можете отлаживать внешний код, написанный на любом языке,

включая Си, С++ и ассемблер. Если код отвечает требованиям для

внешней компоновки и содержит полную стандартную отладочную ин-

формацию, интегрированная среда отладчика может выполнять его по

шагам или трассировать.

Выполнение больших фрагментов

Иногда, конечно, нежелательно выполнять по шагам всю прог-

рамму только для того, чтобы добраться до того места, где возни-

кает проблема. Отладчик дает вам возможность выполнять сразу

большой фрагмент программы до той точки, где вы хотите начать вы-

полнение по шагам.

Чтобы задать в программе точку, до которой вы хотите ее вы-

полнить, а затем остановиться, используйте команду RunіGo To

Cursor (ВыполнениеіВыполнение до курсора) или клавишу F4. (Этим

вы сообщите отладчику, что не хотите выполнять программу по ша-

гам, пока не достигнете заданной точки.) Позиционируйте курсор на

той строке, где вы хотите возобновить управление отладкой, затем

нажмите клавишу F4. Заметим, что вы можете сделать это как в на-

чале сеанса отладки, так и когда уже выполните часть программы по

шагам или протрассируете.

Поиск нужного места

IDE предусматривает два способа поиска в программе заданного

места. Простейший способ предоставляет команда Find Procedure ме-

ню Search. Команда Find Procedure (Поиск процедуры) запрашивает у

вас имя процедуры или функции, затем находит соответствующую

строку в файле, где определяется эта подпрограмма. Этот подход

полезно использовать при редактировании, но его можно комбиниро-

вать с возможностью выполнения программы до определенной точки,

чтобы пройти программу до той части кода, которую вы хотите отла-

дить.

Возврат

Иногда в ходе отладки полезно узнать, как вы попали в данную

часть кода. Окно Call Stack (Стек вызова) показывает вам последо-

вательность вызовов процедур или функций, которые привели к теку-

щему состоянию (глубиной до 128 уровней). Для вывода окна Call

Stack используйте команду DebugіCall Stack.

Окно Call Stack особенно полезно использовать, если вы слу-

чайно начали трассировку кода, который хотели бы выполнить за

один шаг. В стеке вызовов вы можете найти тот вызов, который на-

чали трассировать по ошибке, затем выбрать команду Run to Cursor,

чтобы выполнить за один шаг остальную часть вызова.

Повторное выполнение

В ходе сеанса отладки иногда желательно начать все сначала.

Выберите команду RunіReset Program или нажмите клавиши Ctrl+F2.

Это приведет к полному сбросу, так что выполнение по шагам, или

трассировка начнется в начале основной программы.

Отслеживание вывода программы

При выполнении программы по шагам часто полезно просмотреть

вывод программы, называемый экраном пользователя. В прикладной

программе Windows это достаточно просто, так как программа уже

выполняется в отдельном окне. Однако в DOS это не так легко. К

счастью, Borland Pascal предоставляет вам несколько способов

просмотра экрана пользователя.

Переключение экранов

В любой момент сеанса отладки вы можете выполнять переключе-

ние экрана IDE и экрана пользователя. Чтобы вывести экран пользо-

вателя, нажмите клавиши Alt+F5. Чтобы вернуться в IDE, нажмите

любую клавишу или щелкните "мышью".

При выполнении программы отладчик также может переключать

экраны автоматически. Управлять характером переключения экранов

вы можете с помощью параметров Display Swapping (Переключение эк-

рана) диалогового окна Debugger. По умолчанию задано эффективное

переключение. Это означает, что экран пользователя выводится

только в том случае, если выполняемый оператор выводит информацию

на экран или вызывает процедуру (даже если эта процедура ничего

на экран не выводит). После завершения вывода экран переключается

обратно в IDE.

Вы можете также сообщить отладчику, что переключать экран

нужно на каждой строке, независимо от вывода, или не переключать

их вовсе. Переключение экранов для каждой строки полезно исполь-

зовать, если ваша программа посылает информацию непосредственно

на экран, что может затереть содержимое экрана IDE.

Окно Output

IDE для DOS предусматривает для экрана пользователя окно,

которое называется окном вывода. Выбрав команду меню Debugі

Output, вы можете открыть (вывести на переднем плане) активное

окно, содержащее вывод программы. Настроить размер этого окна

можно аналогично окну редактирования.

Использование двух мониторов

IDE предоставляет вам возможность использования для целей

отладки второго монитора. Этот монитор должен быть монохромным

дисплеем (поскольку использует память, отличную от цветного дисп-

лея), и вам нужно будет запустить IDE с параметром /D. В режиме с

двумя мониторами экран IDE выводится на монохромном экране, вывод

вашей программы - на цветном экране, а переключение экранов не

выполняется.

Просмотр значений

Выполнение программы по шагам или ее трассировка могут по-

мочь вам найти ошибки в алгоритме программы, но обычно желательно

также знать, что происходит на каждом шаге со значениями отдель-

ных переменных. Например, при выполнении по шагам цикла for по-

лезно знать значение переменной цикла. IDE Borland Pascal имеет

два инструментальных средства для проверки содержимого переменных

программы: окно Watches (Просмотр) и диалоговое окно Evaluate and

Modify (Вычисление и модификация).

Что такое выражение?

Оба средства вычисление и просмотра работают на уровне выра-

жений, поэтому важно определить, что считается выражением. Выра-

жение состоит из констант, переменных и структур данных, скомби-

нированных с помощью операций и большинства встроенных функций.

Почти все, что вы можете использовать в правой части оператора

присваивания, может также использоваться в качестве отладочного

выражения. Точные спецификации показаны в Таблице 6.1.

Элементы выражений отладчика Таблица 6.1

ЪДВДДДДДДДДДДДї

і Элемент выражения і Допустимые значения і

ГДЕДДДДДДДДДДДґ

і Константы і Все допустимые типы: Boolean, Byte,і

і і Char, перечислимый тип, Integer,і

і і Longint, Real, Shortint, Word иі

і і строковый тип. і

ГДЕДДДДДДДДДДДґ

і Переменные і Все типы, включая типы, определен-і

і і ные пользователям. і

і і і

і целочисленный тип і Любое целочисленное выражение с пе-і

і і ременными границами диапазона. і

і і і

і тип с плавающей точкойі Любые выражения с плавающей точкойі

і і или целочисленные выражения; лишниеі

і і значащие цифры отбрасываются. і

і і і

і символьный тип і Любое символьное выражение, включаяі

і і печатаемые символы в одинарных ка-і

і і вычках, целочисленные выражения,і

і і тип которых приведен к типу Char, иі

і і контанты ASCII (#xx). і

і і і

і булевский тип і True, False и все булевские выраже-і

і і ния. і

і і і

і перечислимый тип і Любые совместимые перечислимые кон-і

і і станты или целочисленные выраженияі

і і в рамках диапазона, тип которыхі

і і приведен к совместимому перечисли-і

і і мому типу. і

і і і

і указатель і Любые совместимые указатели или вы-і

і і ражения с приведенными к ним типа-і

і і ми; функция Ptr с соответствующимі

і і параметрами. і

і і і

і строковый тип і Любая строковая константа (текст ві

і і одинарных кавычках); строковые пе-і

і і ременные; строковые выражения, сос-і

і і тоящие из конкатенированных строко-і

і і вых констант и переменных. і

і і і

і множество і Любая множественная константа; лю-і

і і бое выражение, совместимое с мно-і

і і жественным типа, в котором исполь-і

і і зуются операции +, - и *. і

ГДЕДДДДДДДДДДДґ

і Приведение типа і Соблюдаются стандартные правилаі

і і Паскаля. і

ГДЕДДДДДДДДДДДґ

і Операции і Все операции Borland Pascal. і

ГДЕДДДДДДДДДДДґ

і Встроенные функции і Все функции, допустимые в выражени-і

і і ях-константах. і

ГДЕДДДДДДДДДДДґ

і Массивы і Массивы Borland Pascal - Mem, MemL,і

і і MemW. і

АДБДДДДДДДДДДДЩ

Просмотр выражений

Если вы хотите отслеживать значение переменной или выражения

при выполнении программы по шагам, то можете открыть окно прос-

мотра Watches. Это окно IDE показывает переменные и их значения в

каждый конкретный момент.

Чтобы открыть окно Watches, выберите команду WindowіWatch.

IDE открывает активное окно Watches без активных записей. Если вы

выберите переменную для просмотра, IDE автоматически открывает

окно Watches (если вы этого еще не сделали).

Добавление просматриваемого выражения

Чтобы добавить в окно Watches переменную, выберите команду

DebugіWatchіAdd Watch или нажмите клавиши Ctrl+F7. Если окно

Watches является активным окном, вы можете добавить выражение

просмотра, нажав клавишу Ins. Отладчик открывает диалоговое окно,

запрашивающее у вас тип просматриваемого выражения. По умолчанию

выражением считается слово в позиции курсора в текущем окне ре-

дактирования. Просматриваемые выражения, которые вы отслеживали

ранее, сохраняются в списке протокола.

Отслеживание текущего просматриваемого выражения

Последнее добавленное или модифицированное просматриваемое

выражение является текущим просматриваемым выражением, которое

указывается выводимым слева от него символом жирной левой точки.

Если окно Watches активно, вы можете также удалить текущее выра-

жение, нажав клавишу Del или Ctrl+Y. Чтобы удалить все просматри-

ваемые выражения, выберите команду DebugіWatchіRemove All

Watches.

Редактирование просматриваемых выражений

Чтобы отредактировать просматриваемое выражение, нужно дваж-

ды щелкнуть на этом выражении "мышью" или сделать это выражение

текущим, затем нажать клавишу Enter или выбрать команду Debugі

WatchіEdit Watch. Отладчик открывает диалоговое окно, аналогичное

тому, которое используется для добавления просматриваемого выра-

жения, которое позволяет вам отредактировать текущее выражение.

При выборе командной кнопки OK или нажатии клавиши Enter отредак-

тированное выражение заменяет оригинал.

Форматирование просматриваемых выражений

Окно Watches позволяет вам несколькими способами форматиро-

вать просматриваемые выражения, добавляя запятую и один или более

спецификаторов формата. Например, хотя целочисленные значения вы-

водятся обычно в десятичном виде, указав после него ,H, вы можете

задать вывод выражения в шестнадцатиричном формате. Допустимые

спецификаторы формата и их действие перечисляются в Таблице 6.2.

Спецификаторы формата в выражениях отладчика

і Символ і Тип, на который і Функция і

і і он влияет і і

ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДЕДґ

і $, H или X і целочисленные типы і Шестнадцатиричный. Выво-і

і і і дит целочисленные значе-і

і і і ния в префиксом $, вклю-і

і і і чая те, которые содержат-і

і і і ся в структуре данных. і

ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДЕДґ

і C і Char, строковые і Символьный. Выводит спе-і

і і типы і циальные символы для ко-і

і і і дов ASCII 0..31. По умол-і

і і і чанию такие символы выво-і

і і і дятся в виде значенийі

і і і #xx. і

ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДЕДґ

і D і целочисленные і Десятичный. Выводят цело-і

і і типы і численные значения в де-і

і і і сятичном виде (включаяі

і і і те, которые содержатся ві

і і і структурах данных). і

ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДЕДґ

і Fn і с плавающей точкой і С плавающей точкой. Выво-і

і і і дит n значащих цифр, гдеі

і і і n лежит в диапазоне 2..18і

і і і (по умолчанию - 11). і

ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДЕДґ

і nM і все і Дамп памяти. Выводит nі

і і і байт памяти, начиная сі

і і і адреса, указываемого вы-і

і і і ражением. Если n не зада-і

і і і но, то по умолчанию оноі

і і і равно значению размера ві

і і і байтах типа переменной. і

ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДЕДґ

і P і указатели і Указатель. Выводит указа-і

і і і тели по адресу сегм:смещі

і і і (на не Ptr(сегм:смещ),і

і і і как это делается по умол-і

і і і чанию. і

ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДЕДґ

і R і записи, объекты і Запись. Выводит имена по-і

і і і лей, например, (X:1;і

і і і Y:10; Z:5) вместо (1, 10,і

і і і 5). і

ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДЕДґ

і S і Char, строки і Строки. Выводит символыі

і і і ASCII 0..31 в виде #xx.і

і і і Использует только для мо-і

і і і дификации дампов памятиі

і і і (см. выше nM). і

АДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДБДЩ

Вычисление и модификация

Кроме добавления просматриваемых выражений при выполнении

программы, отладчик имеет средство, позволяющее вам в любой мо-

мент вычислять выражения и изменять на этапе выполнения значения

переменных.

Вычисление выражений

Чтобы вычислить выражение, выберите команду DebugіEvaluate/

Modify или нажмите клавиши Ctrl+F4. Отладчик выводит диалоговое

окно Evaluate and Modify (Вычисление и модификация). По умолчанию

слово в позиции курсора в текущем окне редактирования выводится

подсвеченным в поле Expression (Выражение). Вы можете отредакти-

ровать это выражение, набрать другое выражение или выбрать вычис-

ляемое вами ранее выражение из списка протокола.

Когда вы нажимаете Enter или щелкаете "мышью" на командной

кнопке Evaluate, текущее значение выражения в поле Expression по-

казывается в поле Result.

Допустимые выражения для вычисления подчиняются тем же пра-

вилам, что и выражения для сравнения. Для вывода результатов вы-

числения выражения действую спецификаторы формата, перечисленные

в Таблице 6.2.

Модификация переменных

Во время отладки с помощью диалогового окна Evaluate and

Modify вы можете изменить значение переменной. Введите переменную

в поле Expression, затем в поле New Value наберите новое значение.

При изменении значений переменных следует иметь в виду сле-

дующее:

* Вы можете изменять только отдельные переменные или элемен-

ты массивов или записей, но не сами массивы и записи.

* Выражения в поле New Value должны отвечать ограничениям

для выражений, перечисленных в Таблице 6.1.

* Выражение в поле New Value (Новое значение) должно в ре-

зультате вычисления давать результат, совместимый по прис-

ваиванию с переменной, которой вы хотите ее присвоить.

Здесь можно руководствоваться следующим правилом: если

присваивание дает при компиляции ошибку, то оно не являет-

ся допустимым значением модификации.

Использование точек останова

Borland Pascal дает вам возможность устанавливать в свое

программе для целей отладки точки останова. Точка останова - это

обозначенная в коде программы позиция, в которой вы хотите прек-

ратить выполнение программы и вернуть выполнение отладчику. В

этом смысле точка останова работает аналогично команде Go to

Cursor, при которой программа выполняется обычным путем до дости-

жения определенной точки. Основное различие состоит в том, что вы

можете задать несколько точке останова и точки останова, которые

будут срабатывать не при каждом их достижении.

Задание точек останова

Чтобы установить в своем в своем коде точку останова, пере-

местите курсор на той строке, где вы хотите остановиться. Строка

должна содержать выполняемый код и не может быть комментарием,

описанием или пустой строкой. Выбор команды Toggle Breakpoint в

локальном меню окна редактирования или нажатие клавиш Ctrl+F8 ус-

танавливает на строке точку останова, которая обозначается подс-

веткой всей строки.

Теперь при выполнении программы из IDE она будет останавли-

ваться при достижении данной строки, но перед ее выполнением.

Строка, содержащая точку останова, выводится при этом в окне ре-

дактирования как строка выполнения. В этот момент вы можете вы-

полнить любые другие действия по отладке (выполнение программы по

шагам, трассировку, просмотр и вычисление).

Отмена точке останова

Чтобы отменить точку останова, поместите курсор на содержа-

щую ее строку и выберите в локальном меню окна редактирования ко-

манду Toggle Breakpoint или нажмите клавиши Ctrl+F8.

Модификация точек останова

В процессе сеанса отладки IDE отслеживает все точки остано-

ва. Вместо того, чтобы шарить по исходному коду в поиске точек

останова, она обслуживать точки останова в одном диалоговом окне

Breakpoints. Для вывода диалогового окна Breakpoints выберите ко-

манду ViewіBreakpoints. В этом диалоговом окне вы можете устанав-

ливать, удалять, редактировать и просматривать свои точки остано-

ва.

Командные кнопки диалогового окна Breakpoints работают сле-

дующим образом:

* Чтобы добавить новую точку останова, подсветите пустую

строку в списке и выберите командную кнопку Edit.

* Чтобы отменить точку останова, подсветите ее и выберите

кнопку Clear.

* Чтобы модифицировать существующую точку останова, подсве-

тите ее и выберите командную кнопку Edit.

* Чтобы найти в своем исходном коде точку останова, подсве-

тите ее и выберите кнопку View.

* Чтобы удалить все точки останова, выберите командную кноп-

ку Clear All.

Создание условный точек останова

Точки останова, добавленные командой Toggle Breakpoint, яв-

ляются безусловными: когда вы попадаете на эту строку, отладчик в

любом случае останавливает программу. Если вы редактируете новую

или существующую точку останова, то у вас есть две дополнительные

возможности - с помощью параметров диалогового окна Edit

Breakpoint вы можете создать условные точки останова. В этих точ-

ках останова вы можете задать два вида условий: счетчик проходов

и логические условия.

Подсчет числа проходов

Задание для точки останова счетчика проходов сообщает отлад-

чику, что останавливать программу нужно не при каждом достижении

точки останова, а только на n-ый раз. То есть, если счетчик про-

ходов равен 3, то отладчик останавливает программу только при

третьем достижении данной точки останова.

Проверка условий

В качестве условия для точки останова можно также задать вы-

ражение типа Boolean. Например, вы можете проверить, попадает ли

переменная в заданный диапазон, или установлен ли некоторый флаг.

В таких условиях для точек останова вы можете задавать любые бу-

левские выражения, подчиняющиеся правилам Таблицы 6.1.

Прерывание программы без точек останова

Даже если вы не установите точек останова, то все равно смо-

жете выйти в отладчик при выполнении программы из IDE. В любой

момент работа программы нажмите клавиши Ctrl+Break. Отладчик на-

ходит позицию в исходном коде, где вы прервали программу. Как и в

случае обычно точки останова вы можете затем выполнить программу

по шагам, трассировать ее, отследить или вычислить выражения.


Глава 7. Модули Borland Pascal

В данной главе разъясняется, что такое модуль, как он ис-

пользуется, какие встроенные модули доступны пользователю, как

писать собственные программные модули и как компилировать их.

Что такое модуль?

Borland Pascal обеспечивает вам доступ к большому числу

встроенных констант, типов данных, переменных, процедур и функ-

ций. Некоторые из них специфичны для Borland Pascal, другие спе-

цифичны для приложений Windows. Их количество велико, однако, в

своей программе вы редко используете их все сразу. Поэтому они

разделены на связанные группы, называемые модулями. В этом случае

можно использовать только те модули, которые необходимы в прог-

рамме.

Используя модули, вы можете разбивать программу на отдельные

части и компилировать их отдельно. Программный модуль (unit)

представляет собой набор констант, типов данных, переменных, про-

цедур и функций, которые могут совместно использоваться несколь-

кими программами. Каждый модуль аналогичен отдельной программе на

Паскале: он может иметь основное тело, которое вызывается перед

запуском вашей программы и осуществляет необходимую инициализа-

цию.

Все описания внутри модуля связаны друг с другом. Например,

модуль Strings содержит все описания, необходимые для подпрограмм

работы со строками с завершающим нулем.

Borland Pascal предоставляет пользователю ряд стандартных

модулей, таких как System, Crt WinCrt и др. Они поддерживают наши

программы Borland Pascal и все записаны в одну из трех библиотех

исполняющей системы (в зависимости от целевой платформы).

Библиотеки исполняющей

системы для целевой платформы Таблица 7.1

ЪВДДДДДДДДДДДДДДДДДДДДДДДДї

і Имя библиотеки і Целевая платформа і

ГЕДДДДДДДДДДДДДДДДДДДДДДДДґ

і TURBO.TPL і DOS реального режима і

і TPW.TPL і Windows і

і TPP.TPL і DOS защищенного режима і

АБДДДДДДДДДДДДДДДДДДДДДДДДЩ

Ваша программа может использовать любую из процедур и функ-

ций в этих модулях, и вам не потребуется писать их заново.

Структура модуля

Структура модуля аналогична структуре программы, однако есть

несколько существенных различий. Например, рассмотрим модуль:

unit <идентификатор>;

interface

uses <список модулей>; { Необязательный }

{ глобальные описания }

implementation

uses <список_модулей>; { Необязательный }

{ локальные описания }

{ реализация процедур и функций }

begin

{ код инициализации }

end.

Заголовок модуля начинается зарезервированным словом unit,

за которым следует имя модуля (идентификатор) точно так же, как и

в случае имени программы. Следующим элементом в модуле является

ключевое слово interface. Оно обозначает начало интерфейсной

секции модуля - части, доступной всем другим модулям или програм-

мам, в которых он используется.

Программный модуль может использовать другие модули, для

этого они определяются в операторе uses. Оператор uses (если он

имеет место) может содержаться в двух местах. Во-первых он может

следовать сразу после ключевого слова interface. В этом случае

любые константы и типы данных, описанные в интерфейсной секции

этих модулей, могут использоваться в любом описании в интерфейс-

ной части данного модуля.

Во-вторых, он может следовать немедленно за ключевым словом

implementation. В этом случае все описания из этих модулей могут

использоваться только в секции реализации.

Интерфейсная секция

Интерфейсная часть - "общедоступная" часть в модуле - начи-

нается зарезервированным словом interface, следует сразу после

заголовка модуля и заканчивается перед зарезервированным словом

implementation. Интерфейс определяет, что является "видимым"

(доступным) для любой программы (или модуля), использующей данный

модуль.

В интерфейсной части (секции) модуля можно определять

константы, типы данных, переменные, процедуры и функции. Как и в

программе, они могут быть расположены в любом порядке, и секции

могут встречаться повторно (например, ваша программа может содер-

жать секцию var, за которой следует секция const, а затем другая

секция var).

Процедуры и функции, видимые для любой программы,

использующей данный модуль, описываются в секции интерфейса,

однако их действительные тела - реализации - находятся в секции

реализации. Вам не нужно использовать описания forward, и они не

допускаются. В интерфейсной части перечисляются все заголовки

процедуры и функции. Секция реализации содержит программную логи-

ку процедур и функций.

Секция реализации

Секция реализации - "приватная" часть - начинается

зарезервированным словом implementation. Все, что описано в

секции интерфейса, является видимым в секции реализации:

константы, типы, переменные, процедуры и функции. Кроме того, в

секции реализации могут быть свои дополнительные описания,

которые не являются видимыми для программ, использующих этот

модуль. Программа не знает об их существовании и не может

ссылаться на них или обращаться к ним. Однако, эти скрытые эле-

менты могут использоваться (и, как правило, используются) "види-

мыми" процедурами и функциями, то есть теми подпрограммами, чьи

заголовки указаны в секции интерфейса.

Оператор uses может содержаться в секции реализации

(implementation) и должен непосредственно следовать за ключевым

словом implementation.

Обычные процедуры и функции, описанные в интерфейсной сек-

ции, то есть те из них, которые не являются подставляемыми

(inline), должны повторно указываются в секции реализации. Заго-

ловок procedure/function должен быть или идентичным тому, который

указан в секции интерфейса, или иметь более краткую форму. В слу-

чае краткой формы наберите ключевое слово (procedure или

function), а за ним укажите имя подпрограммы (идентификатор). За-

тем подпрограмма должна содержать все свои локальные описания

(метки, константы, типы, переменные и вложенные процедуры и функ-

ции), за которыми должно находиться основное тело самой подпрог-

раммы. Пусть в интерфейсной части указаны следующие описания:

procedure ISwap(var V1,V2 : integer);

function IMax(V1,V2 : integer) : integer;

Тогда Секция реализации будет иметь следующий вид:

procedure ISwap; var

Temp := integer;

begin

Temp := V1; V1 := V2; V2 := Temp

end; {конец процедуры Swap}

function IMax(V1,V2 : integer) : integer;

begin

if V1 > V2

then IMax := V1

else IMax := V2

end; { конец функции Max }

Подпрограммы, локальные для секции реализации (то есть не

описанные в секции реализации), должны иметь полный (несокращен-

ный) заголовок procedure/function.

Секция инициализации

Обычно вся секция реализации модуля заключена между зарезер-

вированными словами implementation и end. Однако, если перед end

поместить зарезервированное слово begin, а между ними - операто-

ры, то получившийся составной оператор, очень похожий на основное

тело программы, становится секцией инициализации модуля

(initialization).

Секция инициализации представляет собой место, где инициали-

зируются структуры данных (переменных), которые использует прог-

раммный модуль или которые он делает доступными программе, ис-

пользующей данный модуль. Вы можете использовать эту секцию для

открытия файлов, которые программа использует позднее.

При выполнении программы, использующей некоторый модуль,

секция инициализации этого модуля вызывается перед запуском ос-

новного тела программы. Если программа использует более одного

модуля, то секции инициализации всех модулей вызываются (в поряд-

ке, указанном в операторе uses в программе) перед тем, как выпол-

нить основное тело программы.

Как используются модули?

Модули, которые использует ваша программа, уже оттранслиро-

ваны и хранятся, как машинный код, а не как исходный код на Пас-

кале, поскольку они не являются включаемыми файлами. Даже интер-

фейсная секция хранится в специальном двоичном формате таблицы

идентификаторов, используемом в Borland Pascal. Более того, опре-

деленные стандартные модули хранятся в специальном файле

(TURBO.TPL, TPW.TPL или TPP.TPL) и автоматически загружаются в

память вместе с Borland Pascal.

В результате использование одного или нескольких модулей

очень незначительно увеличивает время компиляции вашей программы

(обычно менее, чем на секунду).

Фактически, если модуль скомпилирован, его использование

сохраняет вам время при перекомпиляции. Поскольку компилятор не

перекомпилирует модуль, пока он не изменяется, использование мо-

дулей в программе ускорит процесс ее построения.

Как указывалось ранее, для использования специального модуля

или набора модулей необходимо в начале программы поместить опера-

тор uses, после которого указать список имен тех модулей, которые

будут использоваться. Имена их должны разделяться запятыми:

program MyProg;

uses thisUnit, thatUnit, theOtherUnit;

Когда компилятор встречает такой оператор uses, он прибавля-

ет информацию из секции интерфейса каждого модуля к таблице иден-

тификаторов и присоединяет машинный код, представленный в секции

реализации, к самой программе.

Модули присоединяются к таблице идентификаторов в указанном

порядке. Порядок модулей в операторе uses значения не имеет. Если

модуль thisUnit использует thatUnit или наоборот, вы можете опи-

сать их в любом порядке, а компилятор определит, какой модуль

нужно скомпоновать с программой MyProg первым. Фактически, если

модуль thisUnit использует thatUnit, но MyProg не вызывает непос-

редственно ни одну из подпрограмм в модуле thatUnit, вы можете

"скрыть" подпрограммы модуля thatUnit, опустив его в операторе

uses:

unit thisUnit;

uses thatUnit;

.

.

.

program MyProg;

uses thisUnit, theOtherUnit;

.

.

.

В этом примере модуль thisUnit может вызывать любую подпрог-

рамму модуля thatUnit, а программа MyProg может вызывать любую из

подпрограмм модуля thisUnit или theOtherUnit. Однако, программа

MyProg не может вызывать подпрограммы модуля thatUnit, поскольку

thatUnit не указывается в операторе uses программы MyProg.

Если в программе не указан оператор uses, Borland Pascal в лю-

бом случае присоединит стандартный модуль System. Этот модуль

обеспечит выполнение некоторых стандартных подпрограмм Borland

Pascal, а также нескольких подпрограмм, специфических для Borland

Pascal.

Ссылки на описания модуля

Как только вы включили модуль в свою программу, все констан-

ты, типы данных, переменные, процедуры и функции, описанные в

секции интерфейса этого модуля, становятся доступными для вашей

программы. Например, допустим, имеется следующий модуль:

unit MyStuff;

interface

const

MyValue = 915;

type

MyStars = (Deneb,Antares,Betelgeuse);

var

MyWord : string[20];

procedure SetMyWord(Star : MyStars);

function TheAnswer : integer;

implementation

.

.

.

end.

Как можно видеть здесь в интерфейсной части модуля, та часть

модуля, которая находится в интерфейсной секции, является видимой

для вашей программы (и может ею использоваться). С учетом этого

можно написать следующую программу:

program TestStuff;

uses MyStuff;

var

I : integer;

AStar : MyStars;

begin

Writeln(myValue);

AStar := Deneb;

SetMyWord(AStar);

Writeln(MyWord);

I := TheAnswer;

Writeln(I)

end.

После включения в программу оператора uses MyStuff вы можете

ссылаться на все идентификаторы, описанные в интерфейсной секции

модуля МyStuff (МyWord, МyValue и так далее). Однако, рассмотрим

следующую ситуацию:

program TestStuff;

uses MyStuff;

const

MyValue = 22;

var

I : integer;

AStar : MyStars;

function TheAnswer : integer;

begin

TheAnswer := 1

end;

begin

Writeln(myValue);

AStar := Deneb;

SetMyWord(AStar);

Writeln(MyWord);

I := TheAnswer;

Writeln(I)

end.

В этой программе переопределяются некоторые из идентификато-

ров, описанных в МyStuff. Будучи скомпилированной и выполненной,

эта программа будет использовать собственные определения для

МyValue и ТheAnswer, поскольку они были описаны позднее, чем оп-

ределения в МyStuff.

Вероятно, вам интересно знать, каким образом в такой ситуа-

ции можно ссылаться на идентификаторы в МyStuff. Для этого необ-

ходимо перед каждым идентификатором помещать имя МyStuff с точкой

(.). Например, рассмотрим еще одну версию этой программы:

program TestStuff;

uses MyStuff;

const

MyValue = 22;

var

I : integer;

AStar : MyStars;

function TheAnswer : integer;

begin

TheAnswer := 1

end;

begin

Writeln(MyStuff.MyValue);

AStar := Deneb;

SetMyWord(AStar);

Writeln(MyWord);

I := MyStuff.TheAnswer

Writeln(I)

end.

Эта третья программа даст такие же ответы, что и первая, да-

же в том случае, если вы переопределите MyValue и TheAnswer. В

действительности вы имели полное право написать первую программу

следующим образом:

program TestStuff;

uses MyStuff;

var

I : integer;

AStar : MyStuff.MyStars;

begin

Writeln(MyStuff.MyValue);

AStar := My.Stuff.Deneb;

MyStuff.SetMyWord(AStar);

Writeln(My.Stuff.MyWord);

I := MyStuff.TheAnswer;

Writeln(I)

end.

Отметим, что имя модуля может предшествовать любому иденти-

фикатору: константе, типу данных, переменной или подпрограмме.

Оператор uses секции реализации

Borland Pascal позволяет вам размещать в секции реализации

оператор uses. В случае его присутствия оператор uses должен сле-

довать непосредственно за ключевым словом implementation (анало-

гично тому, как в интерфейсной секции оператор uses должен следо-

вать непосредственно за ключевым словом interface).

Размещение в секции реализации оператора uses позволяет

"скрыть" внутренние детали модуля, поскольку используемые в сек-

ции реализации модули оказываются "невидимыми" для того, кто этот

модуль использует. Более важным, однако, является то, что это

позволяет вам строить взаимнозависимые модули.

Поскольку программные модули в Borland Pascal не обязаны

иметь строго иерархическую структуру, то допускается использовать

циклические ссылки на модули. О циклических ссылках на модули

рассказывается в Главе 10 "Справочного руководства по языку".

Стандартные модули

Модули библиотек исполняющей системы Borland Pascal загружа-

ются в память вместе с Borland Pascal; вы всегда можете их ис-

пользовать. Обычно библиотеки исполняющей системы (TURВО.TPL,

TPW.TPL и TPP.TPL) находятся в том же каталоге, что и компилятор

(TURBO.EXE. BPW.EXE и BP.EXE).

Создание ваших собственных модулей

Если вы хотите написать модуль, содержащий некоторые полез-

ные подпрограммы, и использовать эти подпрограммы в своих прог-

раммах, напишите модули и сохраните его под именем, заданным в

заголовке модуля. Borland Pascal сохраняет файл с расширением

.PAS, как и любой другой файл, созданный в редакторе Borland

Pascal. В исходном файле может содержаться только один модуль.

Компиляция модуля

Скомпилировать модуль вы можете двумя способами. Вы можете:

* Скомпилируйте модуль с помощью команды CompileіCompile.

Вместо создания файла .EXE Borland Pascal создает файл

.TPU, .TPW или .TPP.

ЪДДДДДДДДДДДДДДДДДДДДДДДДВї

і Целевая платформа і Расширение имени файла і

і і модуля і

ГДДДДДДДДДДДДДДДДДДДДДДДДЕґ

і DOS реального режима і .TPU і

і Windows і .TPW і

і DOS защищенного режима і .TPP і

АДДДДДДДДДДДДДДДДДДДДДДДДБЩ

Например, если ваш модуль называется MYUNIT.PAS, если це-

левой платформой является Windows, он компилируется в

MYUNIT.TWP.

* Для компиляции программы, которая включает в себя оператор

uses, используйте команду CompileіMake или CompileіBuild.

В зависимости от целевой платформы, создается файл .TPU,

.TPW или .TPP.

Примечание: О том, как использовать оператор uses,

рассказывается в следующем разделе.

Доступность модуля для программы

Скопируйте свой новый файл .TPU, .TPW или .TPP в каталог мо-

дулей, заданный в диалоговом окне OptionsіDirectories, или ис-

пользуйте параметр командной строки /U при работе с компилятором

режима командной строки.

Если вы поместите свой модуль в заданный каталог модулей, то

сможете ссылаться на этот модуль, даже если он не находится в те-

кущем каталоге или в библиотеках исполняющей системы.

Включите в любую программу, где вы хотите использовать свой

новый модуль, оператор uses. Например, если ваш новый модуль на-

зывается INTLIB.TPW, то задайте в своей программе оператор следу-

ющего вида:

uses IntLib;

Чтобы найти модуль, имя которого указано в операторе uses,

Borland Pascal проверяет его наличие в библиотеке исполняющей

системы, загруженной в память в время инициализации.

Примечание: О том, как поместить модуль в библиотеку

исполняющей системы, рассказывается ниже.

Если модуль в библиотеке исполняющей системы отсутствует, то

компилятор ищет его на диске, сначала в текущем каталоге, затем в

каталогах, заданных в качестве каталогов модулей (Optionsі

Directories). Компилятор предполагает, что имя файла совпадает с

именем модуля, а расширение имени файла - это .TPU, .TPW или

.TPP. Исходный текст модуля имеет расширение .PAS.

Пример

Теперь напишем небольшой модуль. Назовем его IntLib и вста-

вим в него две простые подпрограммы для целых чисел - процедуру и

функцию:

unit IntLib;

interface

procedure ISwap(var I,J : integer);

function IMax(I,J : integer) : integer;

implementation

procedure ISwap;

var

Temp : integer;

begin

Temp := I; I := J; J := Temp

end; { конец процедуры ISwap }

function IMax;

begin

if I > J

then IMax := I

else IMax := J

end; { конец функции IMax }

end. { конец модуля IntLib }

Наберите этот модуль, запишите его в файл INTLIВ.PAS, а за-

тем скомпилируйте, задав в качестве целевой платформы защищенный

режим DOS. В результате получим код модуля в файле INTLIВ.ТРP.

Перешлем его в каталог модулей (если такой имеется), или оставив

в том же каталоге, где находится следующая программа, которая ис-

пользует модуль IntLib:

program IntTest;

uses IntLib;

var

A,B : integer;

begin

Write('Введите два целочисленных значения: ');

Readln(A,B);

ISwap(A,B);

Writeln('A = ',A,' B = ',B);

Writeln('Максимальное значение равно ',IMax(A,B));

end. { конец программы IntTest }

Модули и большие программы

До сих пор мы говорили о модулях как о библиотеках - наборах

полезных подпрограмм, которые могут использоваться несколькими

программами. Однако, у модуля есть еще одна функция - разбивать

большую программу на составные части.

Два аспекта Borland Pascal способствуют использованию моду-

лей в такой функции:

* высокая скорость компиляции и компоновки;

* способность работать с несколькими файлами одновременно,

например, с программой и несколькими модулями.

Обычно большая программа разбивается на модули, которые

группируют процедуры по их функциям. Например, программа редакто-

ра может быть разделена на части, выполняющие инициализацию, рас-

печатку, чтение и запись файлов, форматирование и так далее. Так-

же, как имеется основная программа, определяющая глобальные конс-

танты, типы данных, переменные, процедуры и функции, так же может

иметь место и "глобальный" модуль, который используется всеми

другими модулями.

Набросок большой программы-редактора может иметь вид:

program Editor;

uses

WinCrt, String { стандартные модули из TPW.TPL }

EditGlobals, { модули, написанные пользователем }

EditInuit,

EditPrint,

EditRead, EditWrite,

EditFormat;

{ описание, процедуры и функции программы }

begin { основная программа }

end. { конец программы Editor }

Модули в данной программе могут содержаться в TPW.TPL, биб-

лиотеке исполняющей системы Windows, или быть отдельными файлами

.TPW. В последнем случае Borland Pascal выполняет за вас управле-

ние проектом. Это означает, что при перекомпиляции программы

Editor с помощью встроенного в компилятор средства формирования

Borland Pascal сравнивает даты каждого файла .PAS и .TPW и пере-

компилирует любой модуль, исходный код которого перекомпилирован.

Другая причина использования модулей в больших программах

состоит в ограничения кодового сегмента. Процессоры 8086 (и родс-

твенные им) ограничивают размер сегмента кода 64 килобайтами. Это

означает, что основная программа и любой данный сегмент на может

превышать 64К. Borland Pascal интерпретирует это, создавая для

каждого модуля отдельный сегмент кода. Без этого объем кода вашей

программы не мог бы превышать 64К.

Примечание: Подробнее о работе с большими программными

проектами рассказывается в Главе 4 "Программирование в ин-

тегрированной среде для DOS".

Утилита TPUMOVER

Допустим, вы хотите добавить стандартным модулям хорошо на-

писанный и полностью отлаженный модуль с тем, чтобы он загружался

в память при запуске компилятора. Переслать его в библиотечный

файл стандартных модулей можно с помощью утилиты TPUMOVER.EXE.

Кроме того, утилита TPUMOVER используется для удаления моду-

лей из библиотечного файла стандартных модулей Borland Pascal,

благодаря чему уменьшается его размер и количество памяти, необ-

ходимой для его загрузки.

Примечание: Более подробно об использовании утилиты

TPUMOVER см. в "Руководстве по инструментальным средствам и

утилитам".

Как вы вероятно поняли, писать собственные модули абсолютно

не сложно. Хорошо написанный, хорошо реализованный программный

модуль упрощает разработку программы; проблемы решаются только

один раз, а не повторно для каждой новой программы. Более того,

использование модулей обеспечивает простое средство для написания

больших программ.


Глава 8. Использование указателей

Указатель - это ссылка на данные или код вашей программы. Он

представляет адрес в памяти элемента, на который указывает. Ис-

пользование указателей позволяет писать большие и более гибкие

программы и особенно полезно, когда вы начинаете писать объект-

но-ориентированные программы.

Данная глава должна помочь вам лучше использовать указатели,

независимо от того, начинаете ли вы работать с Паскалем или уже

давно программируете на Паскале, но раньше не работали с указате-

лями. Она охватывает следующие темы:

* Зачем и когда используются указатели.

* Что такое указатель.

* Как использовать указатели.

* Эффективная работа с указателями.

Для чего используются указатели?

Рано или поздно каждый программист, работающий на Паскале,

попадает в ситуацию, требующую использования указателей. Указате-

ли требуется применять в следующих случаях:

* Если ваша программа работает с большими объемами данных

(общий объем которых превышает 64К).

* Если ваша программа во время компиляция использует данные

неизвестного размера.

* Если программа использует временные буферы данных.

* Если ваша программа работает с несколькими типами данных.

* Если ваша программа использует связанные списки данных или

объектов.

Давайте подробнее рассмотрим каждую причину использования

указателей.

Работа с большими объемами данных

По мере того как программы становятся более сложными, и тре-

буются работа с большим количеством данных, область объемом в

64К, зарезервированная в Borland Pascal для данных, может ока-

заться недостаточной, чтобы содержать все необходимые программе

данные. Указатели позволяют вам обойти эту проблему.

Когда вы описываете в Borland Pascal глобальные переменные,

компилятор выделяет для них память в области, которая называется

сегментом данных. Сегмент данных имеет максимальный размер 64К.

Это означает, что общий объем всех ваших глобальных переменных не

может превышать 64К. Для многих программ этот предел значения не

имеет, но в некоторых случаях вам может потребоваться больший

объем.

Примечание: Локальные переменные не помещаются в сег-

мент данных и в пределе 64К не учитываются.

Предположим, например, что у вас есть программа, требующая

массива в 400 строк по 100 символов каждая. Для этого массива

требуется примерно 40К, что меньше максимума в 64К. Если осталь-

ные ваши переменные помещаются в оставшиеся 24К, массив такого

объема проблемы не представляет.

Но что если вам нужно два таких массива? Это потребовало бы

80К, и 64К сегмента данных не хватит. Чтобы работать с большими

объемами данных, вам нужно использовать динамически распределяе-

мую область памяти. Ваша программа может выделить в динамически

распределяемой области 80К, поддерживая указатель в виде ссылку

на адрес данных. Указатель занимает в сегменте данных только 4

килобайта.

Что такое динамически распределяемая область памяти?

Динамически распределяемая область памяти - это вся память,

которую ваша операционная система делает доступной для программы

и которая не используется ее кодом, сегментом данных и стеком.

Объемом распределяемой динамической памяти вы можете управлять с

помощью директивы компилятора $M.

Обычно в Borland Pascal вы можете зарезервировать память в

динамически распределяемой области, получить к ней доступ через

указатель, а затем снова освободить память. Подробности о распре-

делении памяти в динамически распределяемой области вы можете

найти ниже в разделе "Как использовать указатели?".

Работа с данными неизвестного размера

Некоторые элементы данных Borland Pascal (в частности, стро-

ки и массивы) требуют задания размеров во время компиляции, даже

если при выполнении программы вам не потребуется вся выделенная

память. Простым примером может быть программа, считывающая вводи-

мую пользователем строку, например, имя пользователь. Чтобы запи-

сать имя в обычной строковой переменной, вам потребовалось бы за-

резервировать достаточно памяти для максимальной возможной стро-

ки, даже если набранное имя содержит всего несколько букв. Если

вы распределяете переменные в динамически распределяемой области

памяти во время выполнения, то можете выделить точно столько

байт, сколько необходимо для фактической строки данных.

Это тривиальный пример, но в приложении, содержащем сотни и

тысячи таких элементов данных (таких как множественные окна или

считываемые из файлов списки) выделение точного объема пространс-

тва может вместо ситуации нехватки памяти привести к успешному

выполнению.

Работа с временными буферами данных

Указатели и динамически распределяемая область памяти осо-

бенно полезны в тех случаях, когда вам требуется временное выде-

ление памяти, и вы не хотите удерживать ее на все время выполне-

ния программы. Например, редактору файлов обычно требуется буфер

данных для каждого редактируемого файла. Вместо описания на этапе

компиляции, что вам необходимо определенное число буфером задан-

ного размера, которые всегда распределяются для файлов, вы можете

выделить их столько, сколько необходимо в каждый конкретный мо-

мент, что делает память доступной для других целей.

Другим общим примером использования временной памяти являет-

ся сортировка. Обычно когда вы сортируете большой объем данных,

то делаете копию массива, сортируете копию, а затем записываете

отсортированные данные обратно в исходный массив. Это сохраняет

целостность ваших данных, но требует также наличия во время сор-

тировки двух копий данных. Если вы хотите распределить сортируе-

мый массив в динамически распределяемой памяти, то можете отсор-

тировать его и скопировать обратно в оригинал, а затем уничтожить

сортируемый массив, освободив память для других нужд.

Работа с несколькими типами данных

Одной из общих причин использования указателей является

ссылка на переменные структуры данных, то есть записи или масси-

вы, которые не всегда имеют одну и ту же структуру. Например, вы

можете выделить блок памяти, зарезервированный для "протокола"

элементов строк различной длины, набранных в поле ввода данных.

Чтобы прочитать список протокола, подпрограмма должна просмотреть

блок и найти отдельные строки. Для указания начала блока вы може-

те использовать простой указатель. В этом случае указатель рабо-

тает аналогично передаче функции или процедуре нетипизированного

параметра var - вы просто хотите сообщить, где что-то находится,

без указания того, что это такое.

Примечание: О нетипизированных параметрах-переменных

рассказывается в Главе 9 ("Процедуры и функции") "Руководс-

тва по языку".

Связанные списки

Одним из общих случаев использования указателей является со-

единение связанных списков записи. Во многих простых приложениях

типа баз данных вы можете размещать записи данных в массивах или

типизированных файлах, но иногда требуется что-то более гибкое

чем массив, который имеет фиксированный размер. Распределяя дина-

мические записи, так что каждое поле имеет запись, указывающую на

следующие записи, вы можете построить список, содержащий столько

элементов, сколько вам требуется.

Что такое указатель?

Указатель - это какой-либо адрес в памяти вашего компьютера.

Это может быть адрес переменной, записи данных, либо процедуры

или функции. Обычно вам не важно, где расположен элемент в памя-

ти. Вы можете просто ссылаться на него по имени, и Borland Pascal

знает, где его нужно искать.

Именно это происходит, когда вы описываете переменную. Нап-

ример, если программа включает в себя следующий код, то вы указы-

ваете компилятору на необходимость зарезервировать область в па-

мяти, на которую будете ссылаться по имени SomeNumber.

var SomeNumber: Integer;

Вам не нужно беспокоиться о том, где SomeNumber находится в

памяти. Именно для этого задается имя.

Адрес размещения SomeNumber в памяти можно найти с помощью

операции @. @SomeNumber - это адрес вашей целочисленной перемен-

ной. Вы можете присвоить этот адрес переменной-указателю, то есть

переменной, содержащей адрес данных или кода в памяти.

Ссылочный тип

Чтобы хранить указатели, вам требуется переменная-указатель,

а для создания переменной-указателя вам необходим ссылочный тип

(или тип "указатель"). Простейшим ссылочным типом является стан-

дартный тип с именем Pointer. Переменная типа Pointer - это общий

(нетипизированный) указатель, то есть, просто адрес. Он не содер-

жит информации о том, на что он указывает.

Таким образом, чтобы использовать тот же пример SomeNumber,

вы можете присвоить его адрес переменной-указателю:

var

SomeNumber: Integer;

SomeAddress: Pointer;

begin

SomeNumber := 17; {присвоить SomeNumber значение}

SomeAddress := @SomeNumber; {присвоить SomeAddress адрес}

SomeAddress := Addr(SomeNumber); {другой способ получения

адреса}

end.

Нетипизированные указатели в Паскале не используются, пос-

кольку они очень ограничены. Они наиболее полезны, когда указыва-

емый элемент будет изменяться, так как нетипизированный указатель

совместим с любым другим указателем. Типизированные указатели

значительно более полезны, и как вы узнаете в следующем разделе,

они более надежны.

Типизированные указатели

Обычно вы определяете ссылочные типы, которые указывают на

конкретный вид элемента, например, целое значение или запись дан-

ных. Как вы далее увидите, можно извлечь преимущество из того

факта, что указателю известно, на что он указывает. Чтобы опреде-

лить типизированный указатель, вы можете описать новый тип, опре-

деленный символом каре (^), за которым следуют один или более

идентификаторов. Например, чтобы определить указатель на Integer,

вы можете сделать следующее:

type PIneger = ^Integer;

Теперь вы можете описать переменные типа PInteger. Если вы

не собираетесь часто использовать ссылочный тип, то можете прос-

то описать переменные, как указатели на уже определенный тип.

Например, если вы определили PInteger как ^Integer, то следующие

описания переменной эквивалентны:

var

X: ^Integer:

Y: PInteger;

Разыменование указателей

До сих пор мы видели, как можно присваивать указателям зна-

чения, но если вы не можете получить значения обратно, польза от

этого невелика. Разыменовав типизированный указатель, вы можете

интерпретировать так, как если бы это была переменная типа, на

которую он указывает. Чтобы разыменовать указатель, поместите

символ каре (^) после идентификатора указателя.

Ниже показаны некоторые примеры разыменования указателя:

type PInteger = ^Integer;

var

SomeNumber: Integer; { присвоить SomeNumber 17 }

SomeAddress := @SomeNumber; { SomeAddress указывает на

SomeNumber }

Writeln(SomeNumber); { напечатать 17 }

Writeln(SomeAddress); { не допускается; указатели печатать

нельзя }

Writeln(SomeAddress^); { напечатать 17 }

AnotherAddress := SomeAddress; { также указывает на

SomeNumber }

AnotehrAddress^ := 99; { новое значение для SomeNumber }

Writeln(SomeNumber); { напечатать 99 }

end.

Пример 8.1 Простые примеры разыменования указателей.

Наиболее важными строками в Примере 8.1 являются следующие:

AnotherAddress := SomeAddress; { также указывает на

SomeNumber }

AnotehrAddress^ := 99; { новое значение для SomeNumber }

Если вы поймете разницу между этими двумя операторами, то

поймете основные моменты в использовании указателей. Первый опе-

ратор присваивает адрес переменной AnotherAddress; он сообщает

ей, куда нужно указывать. Второй оператор присваивает новое зна-

чение элементу, на который указывает AnotherAddress. На Рис. 8.1

графически показано, как изменяется переменная.

ЪДДДДДДДДДДїЪДДДДДДДДДДДїЪДДДДДДДДДДДїЪДДДДДДДДДДДї

SomeNumber і 17 іі 17 іі 17 іі 99 і

ГДДДДДДДДДДґГДДДДДДДДДДДґГДДДДДДДДДДДґГДДДДДДДДДДДґ

і не іі іі іі і

SomeAddress іопределеноіі@SomeNumberіі@SomeNumberіі@SomeNumberі

ГДДДДДДДДДДґГДДДДДДДДДДДґГДДДДДДДДДДДґГДДДДДДДДДДДґ

і не іі не іі іі і

AnotherAddressіопределеноііопределено іі@SomeNumberіі@SomeNumberі

АДДДДДДДДДДЩАДДДДДДДДДДДЩАДДДДДДДДДДДЩАДДДДДДДДДДДЩ

^ ^ ^ ^

SomeNumber := 17; і і і

SomeAddress := і і

@SomeNumber; і і

AnotherAddress і

:= SomeAddress: і

AnotherAddress^

:= 99;

Как использовать указатели?

Теперь вы получили достаточно хорошее представление о том, в

каких ситуациях вы можете использовать указатели, и можно расс-

мотреть их фактическое применение. В данном разделе охватываются

следующие темы:

* Распределение динамических переменных.

* Освобождение выделенной для динамических переменных памя-

ти.

* Распределение и освобождение выделенных объемов памяти.

* Проверка доступного в динамически распределяемой области

пространства.

Borland Pascal предусматривает две пары процедур для выде-

ления и освобождения памяти, распределяемой для динамических пе-

ременных. Чаще всего используются процедуры New и Dispose, кото-

рые отвечают большинству потребностей. Процедуры GetMem и FreeMem

выполняют те же функции, но на более низком уровне.

Выделение памяти для динамических переменных

Одним из наиболее важных моментов использования указателей

является распределение динамических переменных в динамически

распределяемой области памяти. Borland Pascal предусматривает два

способа выделения для указателя памяти: процедура New и процедура

GetMem.

Использование New как процедуры

New - это очень простая процедура. После описания перемен-

ной-указателя вы можете вызвать процедуру New для выделения

пространства в динамически распределяемой памяти для указываемого

переменной элемента. Приведем пример:

var

IntPointer: ^Integer;

StringPointer: ^String;

begin

New(IntPointer); { выделяет в динамически распреде-

ляемой области два байта }

New(StringPointer); { выделяет в динамически распреде-

. ляемой области 256 байт }

.

.

end.

Пример 8.2 Распределение динамической переменной с помощью

процедуры New.

После вызова процедуры New переменная-указатель указывает на

память, выделенную в динамически распределяемой памяти. В данном

примере IntPointer указывает на двухбайтовую область, выделенную

процедурой New, а IntPointer^ - это допустимая целочисленная пе-

ременная (хотя это целочисленное значение еще не определено).

Аналогично, StringPointer указывает на выделенный для строки

256-байтовый блок, а его разыменование дает доступную для исполь-

зования строковую переменную.

Использование New как функции

Кроме выделения памяти для конкретной динамической перемен-

ной вы можете использовать New как функцию, возвращающую указа-

тель конкретного типа. Например, если PInteger - это тип, опреде-

ленный как ^Integer, а IntPopinter имеет тип PInteger, то следую-

щие два оператора эквивалентны:

New(IntPointer);

IntPointer := New(PInteger);

Это особенно полезно в случаях, когда может потребоваться

присваивать переменной-указателю элементы различных типов. Иногда

желательно распределять динамическую переменную, не присваивая

явно указатель конкретной переменной. Вероятно, вы можете сделать

это только создав для процедуры и функции параметр:

SomeProcedure(New(PointerType));

В этом случае SomeProcedure будет добавлять передаваемый па-

раметр к некоторому списку. В противном случае распределяемая па-

мять будет потеряна. Библиотеки Borland Turbo Vision и Borland

Pascal широко используют этот метод для присваивания динамических

объектов спискам.

Использование New с объектами

Когда вы используете New как функцию или процедуру для выде-

ления динамического объекта, то можете добавить необязательный

второй параметр, который задает применяемый для инициализации

объекта конструктор. В Примере 8.3 первое обращение к New распре-

деляет пространство для объекта, но не инициализирует этот объ-

ект. Второй вызов выделяет память и вызывает для задания объекта

конструктор Init.

type

PMyObject = ^TMyObject;

TMyObject = object

constructor Init;

end;

var

MyObject, YourObject: PMyObject;

begin

New(MyObject); { объект не инициализируется }

New(YourObject, Init); { вызов Init для инициализации

объекта }

end.

Пример 8.3 Создание динамических объектов.

Примечание: Об объектах и их конструкторах рассказыва-

ется в Главе 9 "Объектно-ориентированное программирование".

Освобождение памяти, выделенной для динамических переменных

Память, распределенная для переменных с помощью New, после

завершения работы с ними должна освобождаться. Это позволит ис-

пользовать динамически распределяемую память для других перемен-

ных. Чтобы освободить память, выделенную для динамической пере-

менной, вы должны использовать процедуру Dispose. В Примере 8.2

вы можете добавить следующее:

Dispose(StringPointer);

Dispose(IntPointer);

Нужно помнить, что если вы распределяете динамические пере-

менные с помощью New, то освобождать выделенную для них память

после завершения работы с этими переменными нужно с помощью

Dispose.

Процедуры GetMem и FreeMem

Иногда нежелательно выделять память тем способом, как это

делает New. Вам может потребоваться выделить больше или меньше

памяти, чем это делает New по умолчанию, либо до начала выполне-

ния вы можете просто не знать, сколько памяти вам нужно использо-

вать. Borland Pascal выполняет такое распределение с помощью про-

цедуры GetMem.

Процедура GetMem воспринимает два параметра: переменную-ука-

затель, для которой вы хотите распределить память, и число расп-

ределяемых байт.

Динамическое выделение памяти для строки

Пусть, например, у вас есть прикладная программа, которая

считывает 1000 строк из файла и записывает их в динамическую па-

мять. Вы не знаете, насколько длинной будет каждая из этих строк,

поэтому вам потребуется описать строковый тип такого размера,

который будет соответствовать максимальной возможной строке. Если

предположить, что не все строки имеют максимальную длину, то у

вас будет бесполезно использоваться память.

Чтобы решить эту проблему, вы можете считать каждую строку в

буфер, затем выделить столько памяти, сколько требуется для фак-

тических данных в строке. Пример этого показан ниже:

type PString = ^String;

var

ReadBuffer: String;

LinewRead: array[1..1000] of PString;

TheFile: Text;

LineNumber: Integer;

begin

Assign(TheFile, 'FOO.TXT');

Reset(TheFile);

for LineNumber := 1 to 1000 do

begin

Readln(ReadBuffer);

GetMem(LinesRead[LineNumber], Length(ReadBuffer) + 1);

LinesRead[LineNumber]^ := ReadBuffer;

end;

end.

Пример. 8.4 Динамическое распределение памяти для строки.

Вместо выделения для строк 256К (256 символов на строку 1000

раз) вы выделили 4К (4 байта на указатель 1000 раз), плюс объем,

фактически занимаемый текстом.

Освобождение выделенной памяти

Аналогично тому, как требуется освобождать память, выделен-

ную с помощью New, вам нужно освобождать память, распределенную с

помощью процедуры GetMem. Это можно сделать с помощью процедуры

FreeMem. Аналогично тому, как каждому вызову New должен соответс-

твовать парный вызов Dispose, каждому вызову процедуры GetMem

должен соответствовать вызов FreeMem.

Как и GetMem, процедура FreeMem воспринимает два параметра:

освобождаемую переменную и объем освобождаемой памяти. Важно,

чтобы объем освобождаемой памяти точно совпадал с объемом выде-

ленной памяти. New и Dispose, основываясь на типе указателя,

всегда знают, сколько байт нужно выделять или освобождать. Но в

случае GetMem и FreeMem объем выделяемой памяти находится всецело

под вашим контролем.

Если вы освободите меньше байт, чем было выделено, то остав-

шиеся байты теряются (происходит "утечка" динамически распределя-

емой памяти). Если вы освободите большее число байт, чем было вы-

делено, то можете освободить память, распределенную для другой

переменной, что может привести к порче данных. В защищенном режи-

ме освобождение большего объема памяти, чем было выделено, вызо-

вет ошибку по нарушению защиты (GP).

Предположим, например, что вы собираетесь выделить память

для одной или более записей данных типа TCheck:

type

PCheck = ^ TCheck;

TCheck = record

Amount: Real;

Mounth: 1..12;

Day: 1..31;

Year: 1990..2000;

Payee: string[39];

end.

Пример 8.5 Простой тип записи.

Каждая запись типа TCheck занимает 50 байт, поэтому, если у

вас есть переменная ThisCheck типа PCheck, вы можете распределить

динамическую запись следующим образом:

GetMem(ThisGheck, 50);

а позднее освободить ее с помощью вызова:

FreeMem(ThisCheck, 50);

Использование с процедурой GetMem функции SizeOf

Однако убедиться, что вы каждый раз выделяете и освобождаете

один и тот же объем памяти, недостаточно. Вы должны обеспечить

распределение правильного объема памяти. Предположим, вы изменили

определение TCheck. Например, если вы переопределили TCheck.Payee

как 50-символьную строку вместо 39-символьной, то не сможете по-

лучить и освобождать достаточно памяти. Надежнее всего использо-

вать в программе функцию SizeOf, например:

GetMem(ThisCheck, SizeOf(TCheck));

.

.

.

FreeMem(ThisCheck, SizeOf(TCheck));

Это не только обеспечивает, что вы выделяете и освобождаете

один и тот же объем, но гарантирует, что при изменении размера

типа ваша программа все равно будет выделять нужную память.

Проверка объема доступной динамически распределяемой памяти

В Borland Pascal определены две функции, возвращающие важную

информацию о динамически распределяемой области памяти: MemAvail

и MaxAvail.

Функция MemAvail возвращает общее число байт, доступных для

распределения в динамической памяти. Перед выделением большого

объема в динамически распределяемой памяти полезно убедиться, что

такой объем памяти доступен.

Функция MaxAvail возвращает размер наибольшего доступного

блока непрерывной памяти в динамически распределяемой области.

Первоначально при запуске программы MaxAvail равно MemAvail, пос-

кольку вся динамически распределяемая область памяти является

доступной и непрерывной. После распределения нескольких блоков

памяти пространство в динамически распределяемой области скорее

всего станет фрагментированным. Это означает, что между частями

свободного пространства имеются распределенные блоки. Функция

MaxAvail возвращает размер наибольшего свободного блока.

Подробнее о том, как Borland Pascal работает с динамически

распределяемой областью памяти, рассказывается Главе 21 ("Вопросы

использования памяти") "Руководства по языку".

Общие проблемы использования указателей

Указатели позволяют вам делать в Паскале некоторые важные

вещи, но есть пара моментов, которые при работе с указателями

нужно отслеживать. При использовании указателей допускаются сле-

дующие общие ошибки:

- разыменование неинициализированных указателей;

- потери динамически распределяемой памяти ("утечки").

Разыменование неинициализированных указателей

Одним из общих источников ошибок при работе с указателями

является разыменование указателя, который еще не был инициализи-

рован. Как и в случае других переменных Паскаля, значение пере-

менной-указателя не будет определено, пока вы не присвоите ей

значение, так что она сможет указывать на какой-то адрес в памя-

ти.

Перед использованием указателей им всегда нужно присваивать

значения. Если вы разыменовываете указатель, которому еще не

присвоено значение, то считанные из него данные могут представ-

лять собой случайные биты, а присваивание значения указываемому

элементу может затереть другие данные, вашу программу или даже

операционную систему. Это звучит несколько пугающе, но при опре-

деленной дисциплине такие вещи легко отслеживаются.

Использование пустого указателя

Чтобы избежать разыменования указателей, которые не указыва-

ют на что-либо значащее, нужен некоторый способ информирования о

том, что указатель недопустим. В Паскале предусмотрено зарезерви-

рованное слово nil, которое вы можете использовать в качестве со-

держательного значения указателей, которые в данный момент ни на

что не указывают. Указатель nil является допустимым, но ни с чем

не связанным. Перед разыменованием указателя вы должны убедиться,

что он отличен от nil (не пуст).

Предположим, например, что у вас есть функция, возвращающая

указатель на некоторый элемент в памяти. Вы можете указать, что

такая функция не может найти элемент, возвращая значение nil.

var ItemPointer: Pointer;

function FindIten: Pointer;

begin

.

.

.

{ найти элемент, возвращая указатель на него или nil,

если элемент не найден }

end;

begin

ItemPointer := nil; { начнем в предположении nil }

ItemPointer := FindItem; { вызвать функцию }

if ItemPointer <> nil then ... { для надежности разымено-

вания ItemPointer }

end.

Потери динамически распределяемой памяти

При использовании динамически распределяемых переменных час-

то возникает общая проблема, называемая утечкой динамической па-

мяти. Утечка памяти - это ситуация, когда пространство выделяется

в динамически распределяемой памяти и затем теряется - по ка-

ким-то причинам ваш указатель не указывает больше на распределен-

ную область, так что вы не можете освободить пространство.

Общей причиной утечек памяти является переприсваивание дина-

мических переменных без освобождения предыдущих. Простейшим слу-

чаем является следующий:

var IntPointer: ^Integer;

begin

New(IntPointer);

New(IntPointer);

end.

Пример 8.6 Простая утечка памяти.

При первом вызове New в динамически распределяемой памяти

выделяется 8 байт, и на них устанавливается указатель IntPointer.

Второй вызов New выделяет другие 8 байт, и IntPointer устанавли-

вается на них. Теперь у вас нет указателя, ссылающегося на первые

8 байт, поэтому вы не можете их освободить. В программе эти байты

будут потеряны.

Естественно, утечка памяти может быть не такой очевидной,

как в Примере 8.6. Выделение памяти почти никогда не происходит в

последовательных операторах, но может выполняться в отдельных

процедурах или далеко отстоящих друг от друга частях программы. В

любом случае лучший способ отслеживания динамических переменных -

это установка их в nil при освобождении. Тогда при попытке расп-

ределить их снова вы можете убедиться что они имеют значение nil:

var IntPointer: ^Integer;

begin

New(IntPointer);

.

.

.

Dispose(IntPointer);

IntPointer := nil;

.

.

.

if IntPointer = nil then New(IntPointer);

end.

Управление связанным списком

Предположим, вы хотите написать программу для ведения своих

личных счетов. Вы можете хранить все данные о счетах в записях,

таких как запись типа TCheck, определенная в Примере 8.5. Но при

написании программы трудно предположить, с каким количеством сче-

тов вам придется иметь дело. Одно из решений здесь состоит в соз-

дании большого массива записей счетов, но это приведет к лишним

затратам памяти. Более элегантное и гибкое решение состоит в рас-

ширении определения записи и включении в нее указателя на следую-

щую запись списка, что приведет к образованию связанного списка,

показанного ниже:

type

PCheck = ^TCheck;

TCheck = record

Amount: Real;

Month: 1..12;

Day: 1..31;

Year: 1990..2000;

Payee: string[39];

Next: PCheck; { указывает на следующую запись }

end.

Пример 8.7 Записи в связанном списке.

Теперь вы можете считать каждую запись счета из файла и вы-

делить для нее память. Если запись находится в конце списка, поле

Next следует сделать равным nil. В вашей программе требуется отс-

леживать только два указателя: первый счет в списке и "текущий"

счет.

Построение списка

Ниже приведена процедура, которая строит связанный список

записей, считывая их из файла. Здесь подразумевается, что вы отк-

рыли файл записей TCheck и именем CheckFile, который содержит по

крайней мере одну запись.

var ListChecks, CurrentCheck: PCheck;

procedure ReadChecks;

begin

New(ListOfChecks); { выделить память для первой записи }

Read(CheckFile, ListOfChecks^); { считать первую запись }

CurrentCheck := ListOfChecks; { сделать первую запись

текущей }

while not Eof(CheckFile do

begin

New(CurrentCheck^.Next); { выделить память для

следующей записи }

Read(CheckFile, CurrentCheck^.Next^); { считать

следующую запись }

CurrentCheck := CurrentCheck^.Next; { сделать следующую

запись текущей }

end;

CurrentCheck^.Next := nil; { после последней считанной

записи следующей нет }

end.

Пример 8.8 Построение связанного списка.

Перемещение по списку

Когда у вас есть список, вы можете легко выполнять поиск в

нем конкретной записи. В Примере 8.9 показана функция, которая

находит первый счет с конкретной суммой и возвращает указатель на

него.

function FindCheckByAmount(AnAmount: Real): PCheck;

var Check: PCheck;

begin

TempCheck := ListOfChecks; { указывает на первую запись }

while (Check^.Amount <> AnAmount) and

(Check^.Next <> nil) do

Check := Check^.Next;

if Check^.Amount = AnAmount then

FindCheckByAmount := Check { возвращает указатель на

найденную запись }

else FindCheckByAmount := nil; { или nil, если таких

записей нет }

end;

Рис. 8.9 Поиск в связанном списке.

Освобождение выделенной для списка памяти

Как показано в процедуре DisposeChecks в Примере 8.10, вы

можете перебрать список, дойдя до каждого элемента и освободив

его.

procedure DisposeChecks;

var Temp: PCheck;

begin

CurrentCheck := ListOfChecks; { указывает на первую

запись }

while CurrentCheck <> nil do

begin

Temp := CurrentCheck^.Next { сохранить указатель Next }

Dispose(CurrentCheck); { освобождение текущей записи }

CurrentCheck := Temp; { сделать сохраненную запись

текущей }

end;

end;

Пример 8.10 Освобождение памяти для связанного списка.


Глава 9. Объектно-ориентированное программирование

Объектно-ориентированное программирование представляет собой

метод программирования, который весьма близко напоминает наше по-

ведение. Оно является естественной эволюцией более ранних новов-

ведений в разработке языков программирования. Объектно-ориентиро-

ванное программирование является более структурным, чем все пре-

дыдущие разработки, касающиеся структурного программирования. Оно

также является более модульным и более абстрактным, чем предыду-

щие попытки абстрагирования данных и переноса деталей программи-

рования на внутренний уровень. Объектно-ориентированный язык

программирования характеризуется тремя основными свойствами:

1. Инкапсуляция. Комбинирование записей с процедурами и

функциями, манипулирующими полями этих записей, формирует

новый тип данных - объект.

2. Наследование. Определение объекта и его дальнейшее ис-

пользование для построения иерархии порожденных объектов

с возможностью для каждого порожденного объекта, относя-

щегося к иерархии, доступа к коду и данным всех порождаю-

щих объектов.

3. Полиморфизм. Присваивание действию одного имени, которое

затем совместно используется вниз и вверх по иерархии

объектов, причем каждый объект иерархии выполняет это

действие способом, именно ему подходящим.

Языковые расширения Borland Pascal предоставляют вам все

средства объектно-ориентированного программирования: большую

структурированность и модульность, большую абстрактность и встро-

енную непосредственно в язык возможность повторного использова-

ния. Все эти характеристики соответствуют коду, который является

более структурированным, более гибким и более легким для обслужи-

вания.

Объектно-ориентированное программирование порой требует от

вас оставить в стороне характерные представления о программирова-

нии, которые долгие годы рассматривались, как стандартные. Однако

после того, как это сделано, объектно-ориентированное программи-

рование становится простым, наглядным и превосходным средством

разрешения многих проблем, которые доставляют неприятности тради-

ционному программному обеспечению.

Дадим хороший совет тому, кто уже имел дело с объектно-ори-

ентированным программированием на других языках. Оставьте в сто-

роне ваши прежние впечатления об объектно-ориентированном прог-

раммировании и изучайте объектно-ориентированные характеристики

Borland Pascal в их собственных терминах. Объектно-ориентирован-

ное программирование не является единственным путем, оно предс-

тавляет собой континуум идей. По своей объектной философии

Borland Pascal больше напоминает С++, чем Smalltalk. Smalltalk

является интерпретатором, тогда как Borland Pascal с самого нача-

ла был чистым компилятором реального кода. Компилятор реального

кода выполняет работу иначе (и значительно быстрее), чем интерп-

ретатор. Borland Pascal был сконструирован, как инструмент разра-

ботки продуктов, а не как инструмент исследования.

Для тех, кто не имеет об этом ни малейшего понятия, мы не

будем подробно объяснять, что такое объектно-ориентированное

программирование. В этот вопрос и так уже внесено достаточно пу-

таницы. Поэтому забудьте о том, что люди говорили вам об объектно

-ориентированное программировании. Наилучший способ (и, фактичес-

ки, единственный) изучить что-либо полезное об объектно-ориенти-

рованное программировании - это сделать то, что вы уже почти сде-

лали: сесть и попытаться узнать все самостоятельно.

Объекты

Посмотрите вокруг себя... и вы обнаружите яблоко, которое вы

купили к завтраку. Допустим, что вы намерены описать яблоко в

терминах программирования. Первое, что вы, возможно, попытаетесь

сделать, так это рассмотреть его по частям; пусть S представляет

площадь кожуры, J представляет содержащийся в яблоке объем жидко-

го сока, F представляет вес фрукта внутри кожуры, D - число семе-

чек...

Не думайте таким образом. Думайте как живописец. Вы видите

яблоко и вы рисуете яблоко. Изображение яблока не есть само ябло-

ко. Оно является символом на плоской поверхности. Но оно не может

быть абстрагировано в несколько чисел, каждое из которых располо-

жено отдельно и независимо где-нибудь в сегменте данных. Его ком-

поненты остаются вместе в их существенной взаимосвязи друг с дру-

гом.

Объекты моделируют характеристики и поведение элементов ми-

ра, в котором мы живем. Они являются окончательной абстракцией

данных.

Примечание: Объекты содержат вместе все свои характе-

ристики и особенности поведения.

Яблоко можно разрезать на части, но как только оно будет

разрезано, оно больше не будет яблоком. Отношения частей к целому

и взаимоотношения между частями становятся понятнее тогда, когда

все содержится вместе в одной упаковке. Это называется инкапсуля-

цией и является очень важным понятием. Немного позже мы к нему

вернемся.

Не менее важным является и тот факт, что объекты могут нас-

ледовать характеристики и поведение того, что мы называем порож-

дающие, родительские объекты (или предки). Здесь происходит ка-

чественный скачок: наследование, возможно, является сегодня

единственным самым крупным различием между обычным программирова-

нием на Паскале и объектно-ориентированным программированием в

Borland Pascal.

Наследование

Целью науки является описание взаимодействий во вселенной.

Большая часть работы в науке при продвижении к цели заключается

просто в построении генеалогических деревьев. Когда энтомолог

возвращается с Амазонки с неизвестным ранее насекомым в банке, то

главной его заботой является определение, где это насекомое рас-

полагается в гигантской схеме, на которой собраны научные назва-

ния всех других насекомых. Аналогичные схемы составлены для рас-

тений, рыб, млекопитающих, рептилий, химических элементов, эле-

ментарных частиц и космических галактик. Все они выглядят как ге-

неалогические деревья: с единой всеобщей категорией в вершине и

все увеличивающимися число категорий, которые лежат ниже этой

единственной категории, и разворачиваются веером по мере прибли-

жения к границам разнообразия.

Внутри категории "насекомые" имеется два подразделения: на-

секомые с видимыми крыльями и насекомые со спрятанными крыльями

или вообще бескрылые. Среди крылатых имеется большее число кате-

горий; мотыльки, бабочки, мухи и т.д. Каждая категория содержит

большое число подкатегорий, а ниже этих подкатегорий может иметь-

ся даже еще большее число подкатегорий (см. Рис. 9.1).

Этот процесс классификации называется таксономией. Это прек-

расная начальная метафора для механизма наследования в объект-

но-ориентированном программировании.

Вопросами, которые задает ученый при попытке классификации

некоторого животного или объекта, являются следующие. В чем этот

объект похож на другие объекты из общего класса? В чем он отлича-

ется от других объектов? Каждый конкретный класс имеет множество

свойств поведения и характеристик, определяющих этот класс. Уче-

ный начинает с вершины конкретного генеалогического дерева и про-

ходит по дочерним областям, задавая себе эти вопросы. Наивысший

уровень самый общий, а вопросы самые простые, например, крылатое

или бескрылое? Каждый последующий уровень является более специфи-

ческим, чем предыдущий, и менее общим. В конце концов, ученый до-

бирается до точки подсчета волосков на третьем сегменте задней

ноги насекомого - что воистину специфично. (И скорее всего о нем

следует сказать, что он не энтомолог.)

ЪДДДДДДДДДДДї

і насекомые і

АДВДДДДДДДВДЩ

ЪДДДДДДДДДДДДДДДЩ і

і і

ЪДДДДБДДДДДї ЪДДДБДДДДДДДї

і крылатые і і бескрылые і

АВДДДВДДДВДЩ АДДДДДДДДДДДЩ

ЪДДДДДДДДЩ і АДДДДДДДї

ЪДДДБДДДДДДїЪДДДДБДДДДїЪДДДДДБДДДДї

і мотыльки іі бабочки іі мухи і

АДДДДДДДДДДЩАДДДДДДДДДЩАДДДДДДДДДДЩ

Рис. 9.1 Таксономическая схема насекомых.

Важно помнить то, что если характеристика однажды определе-

на, то все категории, расположенные ниже данного определения, со-

держат эту характеристику. Таким образом, как только вы определи-

ли насекомое, как члена отряда diptera (мухи), то вам не следует

отмечать снова, что у мух имеется одна пара крыльев. Разновид-

ность насекомых, которую мы зовем мухи, наследует эту характерис-

тику от своего отряда.

Как вы поняли, объектно-ориентированное программирование в

большой степени является процессом построения генеалогического

дерева для структур данных. Одной из важных особенностей, которые

объектно-ориентированное программирование добавляет традиционным

языкам типа Паскаль, является механизм, с помощью которого типы

данных могут наследовать характеристики более простых, более об-

щих типов. Этим механизмом является наследование.

Объекты: наследующие записи

В терминах Паскаля, объект во многом схож с записью, которая

является оболочкой для объединения нескольких связанных элементов

под одним именем. Предположим, вы хотите разработать программу

вывода платежной ведомости, печатающую отчет и показывающую,

сколько нужно выплатить каждому служащему за рабочий день. Запись

можно организовать следующим образом:

TEmployee = record

Name: string[25];

Title: string[25];

Rate: Real;

end;

Примечание: По соглашению все типы начинаются с буквы

T. Вы также можете следовать этому правилу.

Здесь TEmployee является типом записи, т.е. шаблоном, ис-

пользуемым компилятором для создания переменных типа запись. Пе-

ременная типа TEmployee является экземпляром этого типа. Термин

"экземпляр" будет вам нередко встречаться в Паскале. Он постоянно

применяется теми, кто использует методы объектно-ориентированного

программирования, поэтому будет хорошо, если вы начнете мыслить в

терминах типов и экземпляров этих типов.

Вы можете оперировать с типом TEmployee двояко. Вы можете

рассматривать поля Name, Title и Rate по отдельности, а когда о

полях, как о работающих одновременно для описания конкретного

рабочего, вы можете рассматривать их совокупность, как TEmployee.

Предположим, что на вашей фирме работает несколько типов

рабочих. Одни из них имеют почасовую оплату, другие - оклад,

третьи - тарифную ставку и так далее. Ваша программа должна учи-

тывать все эти типы. Вы можете создать другой тип записи для каж-

дого типа рабочего. Например, для получения данных о том, сколько

должен получить рабочий с почасовой оплатой, нужно знать, сколько

часов он отработал. Можно построить запись THourly вида:

THourly = record

Name: string[25];

Title: string[25];

Rate: Real;

end;

Вы можете также оказаться несколько догадливее и сохранить

тип TEmployee путем создания поля типа TEmployee внутри типа

THourly:

THourly = record

Worker: TEmployee;

Time: integer;

end;

Такая конструкция работает, и программисты, работающие на

Паскале, делают это постоянно. Единственное, чего этот метод не

делает, так это то, что он заставляет вас думать о том, с чем вы

работаете в вашем программном обеспечении. Вам следует задаться

вопросом типа; "Чем почасовик отличается от дpугих pабочих?" От-

вет прост: почасовик - это pабочий, котоpому платится за коли-

чество часов pаботы. Продумайте снова первую часть предложения;

почасовик - это pабочий...

Теперь вы поняли!

Запись для pаботника-почасовика hourly должна иметь все за-

писи, котоpые имеются в записи employee. Tип THourly является до-

черним типом для типа TEmployee. THourly наследует все, что при-

надлежит TEmployee, и кроме того имеет кое-что новое, что делает

THourly уникальным.

Этот процесс, с помощью которого один тип наследует характе-

ристики другого типа, называется наследованием. Наследник называ-

ется порожденным (дочерним) типом, а тип, которому наследует до-

черний тип, называется порождающим (родительским) типом.

Ранее известные типы записей Паскаля не могут наследовать.

Однако Borland Pascal расширяет язык Паскаль для поддержки насле-

дования. Одним из этих расширений является новая категория струк-

туры данных, связанная с записями, но значительно более мощная.

Типы данных в этой новой категории определяются с помощью нового

зарезервированного слова object. Тип объекта может быть определен

как полный, самостоятельный тип в манере описания записей Паска-

ля, но он может определяться и как потомок существующего типа

объекта путем помещения порождающего (родительского) типа в скоб-

ки после зарезервированного слова object.

В приводимом здесь примере платежной ведомости два связанных

типа объектов могли бы определяться следующим образом:

type

TEmployee = object

Name: string[25];

Title: string[25];

Rate : Real;

end;

THourly = object(TEmployee)

Time : Integer;

end;

Примечание: Обратите внимание, что здесь использование

скобок означает наследование.

Здесь TEmployee является родительским типом, а THourly - до-

черним типом. Как вы увидите чуть позднее, этот процесс может

продолжаться неопределенно долго. Вы можете определить дочерний

тип THourly, дочерний к типу THourly тип и т.д. Большая часть

конструирования объектно-ориентированных прикладных программ сос-

тоит в построении такой иерархии объектов, являющейся отражением

генеалогического дерева объектов в приложениях.

Все возможные типы, наследующие тип TEmployee, называются

дочерними типами типа TEmployee, тогда как THourly является не-

посредственным дочерним типом типа TEmployee. Наоборот, TEmployee

является непосредственным родителем типа THourly. Тип объекта (в

точности как подкаталог в DOS) может иметь любое число непосредс-

твенных дочерних типов, но в то же время только одного непосредс-

твенного родителя.

Как показали данные определения, объекты тесно связаны с за-

писями. Новое зарезервированное слово object является наиболее

очевидным различием, но как вы увидите позднее, имеется большое

число других различий, некоторые из которых довольно тонкие.

Например, поля Name, Title и Rate в типе TEmployee не указа-

ны явно в типе THourly, но в любом случае тип THourly содержит их

благодаря свойству наследования. Вы можете говорить о величине

Name типа THourly в точности так же, как о величине Name типа

TEmployee.

Экземпляры объектных типов

Экземпляры объектных типов описываются в точности так же,

как в Паскале описывается любая переменная, либо статическая, ли-

бо указатель, ссылающийся на размещенную в динамической памяти

переменную:

type

PHourly = ^THourly;

var

StatHourly: THourly; { готово }

DynaHourly: PHourly; { перед использованием память должна

выделяться с помощью New }

Поля объектов

Вы можете обратиться к полю объекта в точности так же, как к

полю обычной записи, либо с помощью оператора with, либо путем

уточнения имени с помощью точки. Например:

AnHourly.Rate := 9.45;

with AnHourly do

begin

Name := 'Sanderson, Arthur';

Title := 'Word processor';

end;

Примечание: Не забывайте о том, что наследуемые поля

объектов не интерпретируются особым образом только потому,

что они являются наследуемыми.

Именно сейчас вы должны запомнить (в конце концов это придет

само собой), что наследуемые поля являются столь же доступными,

как если бы они были объявлены внутри типа объекта. Например, да-

же если Name, Title и Rate не являются частью описания типа

THourly (они наследованы от типа TEmployee), то вы можете ссы-

латься на них, словно они описаны в THourly:

AnHourly.Name := 'Arthur Sanderson';

Хорошая и плохая техника программирования

Даже если вы можете обратиться к полям объекта непосредс-

твенно, это будет не совсем хорошей идеей. Принципы объектно-ори-

ентированного программирования требуют, чтобы поля объектов были

исключены из исходного кода, насколько это возможно. Это ограни-

чение поначалу может показаться спорным и жестким, но оно являет-

ся только частью огромной картины объектно-ориентированное прог-

раммирования, которую мы нарисуем в этой главе. Со временем вы

увидите смысл, скрытый в этом новом определении хорошей практики

программирования, хотя имеются некоторые основания приоткрыть его

перед тем, как все придет само. А пока же примите на веру: избе-

гайте прямого обращения к полям данных.

Примечание: Borland Pascal позволяет вам делать поля

объекта и его методы частными. Подробнее об этом рассказы-

вается ниже.

Итак, как же обращаться к полям объекта? Как читать их и как

присваивать им значения?

Примечание: Поля данных объекта - это то, что объект

"знает", а методы объекта - это то, что объект "делает".

Ответом заключается в том, что при всякой возможности для

доступа к полям данных должны использоваться методы объекта. Ме-

тод является процедурой или функцией, описанной внутри объекта и

жестко ограниченной этим объектом.

Методы

Методы являются одними из наиболее примечательных атрибутов

объектно-ориентированное программирования и требуют некоторой

практики перед использованием. Вернемся сначала к исходному воп-

росу о тщетной попытке структурного программирования, связанной с

инициализацией структур данных. Рассмотрим задачу инициализации

записи со следующим определением:

TEmployee = object

Name: string[25];

Title: string[25];

Rate: Real;

end;

Большинство программистов использовали бы оператор with для

присвоения полям Name, Title и Rate начальных значений:

var

MyEmployee: Employee;

with MyEmployee do

begin

Name := 'Sanderson, Arthur';

Title := 'Word processor';

Rate := 9.45;

end;

Это тоже неплохо, но здесь мы жестко ограничены одной специ-

фическим экземпляром записи - MyEmployee. Если потребуется иници-

ализировать более одной записи типа Employee, то вам придется ис-

пользовать большее число операторов with, которые выполняют в

точности те же действия. Следующим естественным шагом является

создание инициализирующей процедуры, которая обобщает оператор

with применительно к любому экземпляру типа TEmployee, пересылае-

мой в качестве параметра:

procedure InitTEmployee(var Worker: TEmployee; AName,

ATitle: String; ARate: Real);

begin

with Worker do

begin

Name := NewName ;

Title := NewTitle;

Rate := NewRate;

end;

end;

Это будет работать, все в порядке, однако если вы почувству-

ете, что при этом тратите больше времени, чем необходимо, то вы

почувствуете то же самое, что чувствовал ранний сторонник объект-

но-ориентированного программирования.

Это чувство значит, что, ну, скажем, вы разрабатываете про-

цедуру InitTEmployee специально для обслуживания типа TEmployee.

Тогда почему вы должны помнить, какой тип записи и какой его эк-

земпляр обрабатывает InitTEmployee? Должен существовать некоторый

путь объединения типа записи и обслуживающего кода в одно единое

целое.

Такой путь имеется и называется методом. Метод - это проце-

дура или функция, объединенная с данным типом столь тесно, что

метод является как бы окруженным невидимым оператором with, что

делает экземпляр данного типа доступными изнутри для метода. Оп-

ределение типа включает заголовок метода. Полное определение ме-

тода квалифицируется в имени типа. Тип объекта и метод объекта

являются двумя лицами этой новой разновидности структуры, именуе-

мой методом.

type

TEmployee = object

Name, Title: string[25];

Rate: Real;

procedure Init (NewName, NewTitle: string[25];

NewRate: Real);

end;

procedure TEmployee.Init (NewName, NewTitle: string[25];

NewRate: Real);

begin

Name := NewName ; { Поле Name объекта TEmployee }

Title := NewTitle; { Поле Tutle объекта TEmployee }

Rate := NewRate; { Поле Rate объекта TEmployee }

end;

Теперь для инициализации экземпляра типа TEmployee вы просто

вызываете его метод, словно метод является полем записи, что име-

ет вполне реальный смысл:

var

AnEmployee: TEmployee;

AnEmployee.Init('Sara Adams, Account manager, 15000');

{пpосто, не так ли?}

Совмещенные код и данные

Одним из важнейших принципов объектно-ориентированного прог-

раммирования является то, что программист во время разработки

программы должен думать о коде и о данных совместно. Ни код, ни

данные не существуют в вакууме. Данные управляют потоком кода, а

код манипулирует образами и значениями данных.

Если ваши код и данные являются разделенными элементами, то

всегда существует опасность вызова правильной процедуры с невер-

ными данными или ошибочной процедуры с правильными данными. Забо-

та о совпадении этих элементов возлагается на программиста, и хо-

тя строгая типизация Паскаля здесь помогает, самое лучшее, что он

может сделать - это указать на несоответствие.

О том, что действительно существует вместе, Паскаль нигде не

сообщает. Если это не отмечено комментарием или не то, о чем вы

все время помните, то вы играете с судьбой.

Объект осуществляет синхронизацию кода и данных путем сов-

местного построения их описаний. Реально, чтобы получить значение

одного из полей объекта, вы вызываете относящийся к этому объекту

метод, который возвращает значение нужного поля. Чтобы присвоить

полю значение, вы вызываете метод, который назначает данному полю

новое значение.

Однако, Borland Pascal не вынуждает вас делать это. Как вся-

кое структурное программирование, объектно-ориентированное прог-

раммирование является дисциплиной, которую вы должны навязать се-

бе, используя предоставляемые языком средства. Borland Pascal

позволяет вам обращаться к полям объекта непосредственно извне

объекта, однако он поощряет вас использовать преимущества объект-

но-ориентированного программирования и создавать методы для мани-

пулирования полями объекта внутри самого объекта. Borland Pascal

позволяет задать принудительную инкапсуляцию с помощью использо-

вания описания private в объявлении объекта.

Примечание: Подробнее о принудительной инкапсуляции

рассказывается ниже в разделе "Секция private".

Определение методов

Процесс определения методов объектов напоминает модули

Borland Pascal. Внутри объекта метод определяется заголовком про-

цедуры или функции, действующей как метод:

type

TEmployee = object

Name, Title: string[25];

Rate: Real;

procedure Init (AName, ATitle: String; ARate: Real);

function GetName : String;

function GetTitle : String;

function GetRate : Real;

end;

Примечание: Поля данных должны быть описаны перед пер-

вым описанием метода.

Как и описания процедур и функций в интерфейсной секции мо-

дуля (interface), описание методов внутри объекта говорит, что

методы делают, но не говорит, как.

Это определяется вне определения объекта, в отдельном описа-

нии процедуры или функции. Если метод полностью определяется вне

объекта, то имени метода должно предшествовать имя типа объекта,

которому принадлежит этот метод, с последующей точкой:

procedure TEmployee.Init(AName, ATitle: string;ARate: Real);

begin

Name := AName;

Title := ATitle;

Rate := ARate;

end;

function TEmployee.GetName: String;

GetName := Name;

end;

function TEmployee.GetTitle: String;

begin

GetTitle := Title;

end;

function TEmployee.GetRate: Real;

begin

GetRate := Rate;

end;

Метод опpеделения следует методу интуитивного pазделения

точками для указания поля записи. Кpоме наличия опpеделения

TEmployee.GetName можно было бы опpеделить пpоцедуpу с именем

GetName, в имени котоpой нет пpедшествующего идентификатоpа

TEmployee. Однако, такая "внешняя" GetName не будет иметь никакой

связи с объектом типа TEmployee и будет только запутывать смысл

пpогpаммы.

Область действия метода и параметр Self

Заметьте, что ни в одном из предыдущих примеров конструкция:

with объект do... не встречается в явном виде. Поля данных объек-

та легко доступны с помощью методов объекта. Хотя в исходном коде

поля данных объекта и тела методов разделены, на самом деле они

совместно используют одну и ту же область действия.

Именно поэтому один из методов TEmployee может содержать

оператор GetTitle := Title без какого-либо квалификатора перед

Title. И именно поэтому Title принадлежит тому объекту, который

вызывает метод. Если объект вызывает метод, то выполняется неяв-

ный оператор with myself do method, связывающий объект и его ме-

тоды в области действия.

Неявный оператор with выполняется путем передачи невидимого

параметра методу всякий раз, когда этот метод вызывается. Этот

параметр называется Self и в действительности является 32-разряд-

ным указателем на экземпляр объекта, осуществляющего вызов мето-

да. Относящийся к TEmployee метод GetRate приблизительно эквива-

лентен следующему:

function TEmployee.GetRate(var Self: TEmployee): integer;

begin

GetRate := Self.Rate;

end;

Примечание: Синтаксически этот пример не совсем кор-

ректен. Он приведен только затем, чтобы дать вам более пол-

ное представление о специфической связи между объектом и

его методом.

Но важно ли вам знать о существовании параметра Self? Обычно

нет. Генерируемый Borland Pascal код выполняет все это автомати-

чески. Однако в некоторых немногочисленных случаях вы можете за-

хотеть проникнуть внутрь метода и использовать параметр Self яв-

но.

Примечание: Явное использование параметра Self допуска-

ется, но вы должны избегать ситуаций, в которых это требует-

ся.

Параметр Self является частью физического кадра стека при

всех вызовах методов. Методы, используемые как внешние на языке

Ассемблера, должны учитывать Self при получении доступа к пара-

метрам метода в стеке.

Примечание: Более подробно об использовании методом

границ стека рассказывается в Главе 22 "Руководства по язы-

ку".

Поля данных объекта и формальные параметры метода

Выводом из того факта, что методы и их объекты разделяют об-

щую область действия, является то, что формальные параметры мето-

да не могут быть идентичными любому из полей данных объекта. Это

является не каким-то новым ограничением, налагаемым объектно-ори-

ентированным программированием, а скорее теми же самыми старыми

правилами области действия, которые Паскаль имел всегда. Это то

же самое, что и запрет для формальных параметров процедуры быть

идентичными локальным переменным этой процедуры:

procedure CrunchIt(Crunchee: MyDataRec,

Crunchby, ErrorCode: integer);

var

A, B: char;

ErrorCode: integer;

begin

.

.

.

Локальные переменные процедуры и ее формальные параметры

совместно используют общую область действия и поэтому не могут

быть идентичными. Вы получите сообщение "Error 4: Duplicate

identifier" (Ошибка 4; Повторение идентификатора), если попытае-

тесь компилировать что-либо подобное, та же ошибка возникает при

попытке присвоить формальному параметру метода имени поля объек-

та, которому данный метод принадлежит.

Обстоятельства несколько отличаются, так как помещение заго-

ловка процедуры внутрь структуры данных является намеком на нов-

шество в Турбо Паскале, но основные принципы области действия

Паскаля не изменились.

Объекты, экспортируемые модулями

Имеет смысл определять объекты в модуле посредством описаний

типа объекта в интерфейсной части модуля, а тела процедур и мето-

ды объекта - в секции реализации. Для определения объекта в моду-

ле не требуется никаких специальных соглашений.

Примечание: Экспортируемый - означает "определенный в

интерфейсной части модуля".

Модули могут иметь свои собственные приватные (частные) оп-

ределения типов объектов внутри выполняемой секции, и эти типы

подвержены тем же ограничениям, как и всякие другие типы, опреде-

ленные в секции реализации. Типы объектов, определенные в интер-

фейсной части модуля, могут иметь дочерние типы объектов, опреде-

ленные в секции реализации модуля. В том случае, когда модуль B

использует модуль A, модуль B также может определять дочерние ти-

пы любого типа объекта, экспортируемого модулем A.

Описанные ранее типы объектов и методы можно определить в

модуле, как показано в программе WORKERS.PAS на дистрибутивном

диске. Чтобы использовать типы объектов и методы, определенные в

модуле Workers, вы можете просто использовать этот модуль в своей

программе и описать экземпляр типа THourly в секции переменных

программы:

program HourPrt;

uses WinCrt, Workers;

var

AnHourly: THourly;

.

.

.

Для создания и вывода фамилии pабочего-почасовика, его долж-

ности и pазмеpа выплаты, пpедставленной пеpеменной AnHourly, вы

просто вызываете методы AnHourly, используя следующий синтаксис:

AnHourlye.Init('Sara Adams', 'Account manager', 1400);

{ записывает в экземпляp THourly }

{ данные для Саpы Адамс: фамилию, }

{ должность и pазмеp выплаты. }

AnHourly.Show;

Примечание: Объектами могут быть также типизированные

константы.

Объекты, будучи очень схожими с записями, могут использо-

ваться внутри оператора with. В этом случае указание имени объек-

та, являющегося собственником методов, не является необходимым:

with AnHourly do

begin

Init('Sara Adams', 'Account manager', 1400);

Show;

end;

Как и в случаях с записями, объекты могут передаваться в ка-

честве параметра процедуре и (как вы увидите позднее) могут раз-

мещаться в динамически распределяемой памяти.

Секция private

В некоторых случаях у вас могут иметься части описаний объ-

ектов, которые экспортировать нежелательно. Например, вы можете

предусмотреть объекты для других программистов, которые они могут

использовать, но не могут непосредственно манипулировать с данны-

ми объекта. Чтобы облегчить это, Borland Pascal позволяет зада-

вать внутри объектов приватные (закрытые) поля и методы.

Приватные поля и методы доступны только внутри того модуля,

в котором описан объект. В предыдущем примере, если бы тип

THourly содержал приватные поля, то доступ к ним можно было бы

получить только в модуле THourly. Даже если другие части объекта

THourly можно было бы экспортировать, (части, описанные, как при-

ватные, были бы недоступными.

Приватные поля и методы описываются непосредственно после

обычных полей и методов, вслед за зарезервированным словом

private. Таким образом, полный синтаксис описания объекта будет

следующим:

type

NewObject = object(родитель)

поля; { общедоступные }

методы; { общедоступные }

private

поля; { приватные }

методы; { приватные }

end;

Программирование в "действительном залоге"

Большая часть из того, что говорилось об объектах до сих

пор, исходит из удобств и перспектив Borland Pascal, поскольку

наиболее вероятно, что это именно то, с чего вы начнете. Теперь

начнутся изменения, поскольку мы подошли к концепциям объект-

но-ориентированного программирования с помощью некоторых принци-

пов программирования на стандартном Паскале. Объектно-ориентиро-

ванное программирование имеет свое собственное отдельное множест-

во понятий, частично благодаря началам объектно-ориентированного

программирования (до некоторой степени ограниченным) в научных

кругах, однако также и потому, что эта концепция действительно

является радикально отличной от других.

Примечание: Объектно-ориентированные языки однажды ме-

тафорично назвали "языками актеров".

Одним, часто забавным, следствием этого явилось то, что объ-

ектно-ориентированное программирование фанатично "одушевляет"

свои объекты. Отныне данные для вас не емкости, которые вы можете

наполнять значениями. С точки зрения нового взгляда на вещи, объ-

екты выглядят как актеры на подмостках со множеством заученных

ролей (методов). Если вы (директор) даете им слово, то актеры на-

чинают декламировать в соответствии со сценарием.

Было бы полезно представить функцию AnHourly.GetPayAmount

как, например, дающую распоряжение объекту AnHourly "Вычислить

размер вашей ежедневной платы". Центральной концепцией здесь яв-

ляется объект. Этот объект обслуживают как список методов, так и

список полей данных, содержащихся в объекте. И ни код, ни данные

не являются здесь "директором".

Чтобы быть совсем привлекательным, объект не может быть опи-

сан как актер на сцене. Образцу объектно-ориентированного прог-

раммирования с большим трудом удается моделировать составляющие

проблемы как компоненты, а не как логические абстракции. Случай-

ности и закономерности, наполняющие нашу жизнь (от тостеров до

телефонных звонков по поводу махровых полотенец) все имеют харак-

теристики (данные) и линии поведения (методы). Характеристики

тостера могут включать требуемое напряжение, число гренок, кото-

рые он может поджарить одновременно, установку слабого или силь-

ного уровней поджаривания, цвет тостера, его фабричную марку и т.

д. Его поведение может включать загрузку кусков хлеба, поджарива-

ние этих кусков и автоматическое выталкивание готовых гренок на-

ружу.

Если мы хотим написать программу имитации кухни, то какой же

имеется наилучший способ смоделировать различные приспособления,

кроме объектов, с их характеристиками и линиями поведения, зако-

дированными в поля данных и в методах? Фактически, это уже сдела-

но: один из первых объектно-ориентированных языков (Симула-67)

был создан как язык для написания таких имитаций.

Есть также причина того, что объектно-ориентированное прог-

раммирование довольно крепко связано в традиционном смысле с ори-

ентированной на построение графиков средой. Объекты должны быть

моделями, и есть ли лучший способ смоделировать объект, чем нари-

совать его изображение? Объекты в Borland Pascal должны имитиро-

вать компоненты проблему, которую вы пытаетесь разрешить. Примите

это во внимание, если в дальнейшем вы намерены эксплуатировать

новые объектно-ориентированные расширения Borland Pascal.

Инкапсуляция

Объединение в объекте кода и данных называется инкапсуляци-

ей. Возможно вы сможете предоставить достаточное количество мето-

дов, благодаря чему пользователь объекта никогда не будет обра-

щаться к полям объекта непосредственно. Некоторые другие объектно

-ориентированные языки, например Smalltalk, требуют обязательной

инкапсуляции, однако в Borland Pascal у вас есть выбор, а хорошая

практика объектно-ориентированного программирования во многом за-

висит от вашей добросовестности.

Объекты TEmployee и THourly написаны таким образом, что со-

вершенно исключена необходимость прямого обращения к их внутрен-

ним полям данных:

type

TEmployee = object

Name, Title: string[25];

Rate: Real;

procedure Init (AName, ATitle: string; ARate: Real);

function GetName : String;

function GetTitle : String;

function GetRate : Real;

function GetPayAmount : Real;

end;

THourly = object(TEmployee)

Time: Integer;

procedure Init(AName, ATitle: string; ARate:

Real, Atime: Integer);

function GetPayAmount : Real;

end;

Здесь присутствуют только четыpе поля данных: Name, Title,

Rate и Time. Методы ShowName и ShowTitle выводят фамилию pаботаю-

щего и его должность, соответственно. Метод GetPayAmount исполь-

зует Rate, а в случае pаботающего THourly и Time для вычисления

суммы выплат pаботающему. Здесь уже нет необходимости обpащаться

непосpедственно к этим полям данных.

Предположив существование экземпляра AnHourly типа THourly,

вы могли бы использовать набор методов для манипулирования полями

данных AnHourly, например:

with AnHourly do

begin

Init ('Allison Karlon, Fork lift operator' 12.95, 62);

{ Выводит на экpан фамилию, должность и сумму выплат}

Show;

end;

Обратите внимание, что доступ к полям объекта осуществляется

не иначе, как только с помощью методов этого объекта.

Методы: никакого ухудшения

Добавление этих методов незначительно увеличивает объем ис-

ходного кода, однако развитый компоновщик Borland Pascal выбрасы-

вает код любого метода, который ни разу не вызывается в програм-

ме. Поэтому вам не следует отступать при предоставлении объекту

того или иного метода, который имеет одинаковые шансы быть как

использованным, так и неиспользованным в каждой программе, в ко-

торой задействован данный тип объекта. Неиспользуемые методы ни-

чего не будут стоить вам как в части качества выполнения програм-

мы, так и в части ее размера, - если они не используются в прог-

рамме, то они попросту отсутствуют в ней.

Замечание по поводу абстрактности данных: Имеется громадное

преимущество в возможности полностью отсоединить THourly от гло-

бальных ссылок. Если ничто вне объекта не "знает" о представлении

его внутренних данных, то программист, контролирующий объект, мо-

жет изменять детали внутреннего представления данных до тех пор,

пока не изменится заголовок метода.

Внутри самого объекта данные могут быть представлены в виде

массива, однако позднее (возможно, что сфера действия прикладной

программы расширяется и объем ее данных растет) в качестве более

эффективного представления данных может быть признано двоичное

дерево. Если объект полностью инкапсулирован, изменение представ-

ления данных с массива на двоичное дерево вообще не изменит ис-

пользование объекта. Интерфейс с объектом останется полностью тем

же, позволяя программисту изящно приспосабливать эксплуатационные

качества объекта без изменения кода, использующего объект.

Расширяющиеся объекты

Люди, которые впервые сталкиваются с Паскалем, зачастую счи-

тают само собой разумеющейся гибкость стандартной процедуры

Writeln, которая позволяет единственной процедуре обрабатывать

параметры многих различных типов:

Writeln(CharVar); { Вывести значение символьного типа }

Writeln(IntegerVar); { Вывести целое значение }

Writeln(RealVar); { Вывести значение с плавающей

точкой }

К сожалению, стандартный Паскаль не предоставляет лично вам

никаких возможностей для создания столь же гибких процедур.

Объектно-ориентированное программирование решает эту пробле-

му с помощью наследования: если определен порожденный тип, то ме-

тоды порождающего типа наследуются, однако при желании они могут

переопределяться. Для переопределения наследуемого метода попрос-

ту опишите новый метод с тем же именем, что и наследуемый метод,

но с другим телом и (при необходимости) с другим множеством пара-

метров.

Простой пример прояснит как процесс так и его смысл. Давайте

определим дочерний по отношению к TEmployee тип, пpедставляющий

pаботника, котоpому платится часовая ставка:

const

PayPeriods = 26; { периоды выплат }

OvertimeThreshold = 80; { на период выплаты }

OvertimeFactor = 1.5; { почасовой коэффициент }

type

THourly = object(TEmployee)

Time: Integer;

procedure Init(AName, ATitle: string; ARate:

Real, Atime: Integer);

function GetPayAmount : Real;

end;

procedure THourly.Init(AName, ATitle: string;

ARate: Real, Atime: Integer);

begin

TEmployee.Init(AName, ATitle, ARate);

Time := ATime;

end;

function THourly.GetPayAmount: Real;

var

Overtime: Integer;

begin

Overtime := Time - OvertimeThreshold;

if Overtime > 0 then

GetPayAmount := RoundPay(OvertimeThreshold * Rate +

Rate OverTime * OvertimeFactor * Rate)

else

GetPayAmount := RoundPay(Time * Rate)

end;

Человек, котоpому платится часовая ставка, является pаботаю-

щим: он обладает всем тем, что мы используем для опpеделения объ-

екта TEmployee (фамилией, должностью, ставкой), и лишь количество

получаемых почасовиком денег зависит от того, сколько часов он

отpаботал за пеpиод, подлежащий оплате. Таким обpазом, для

THourly тpебуется еще и поле вpемени, Time.

Так как THourly опpеделяет новое поле, Time, его инициализа-

ция тpебует нового метода Init, котоpый инициализиpует и вpемя, и

наследованные поля. Вместо того, чтобы непосpедственно пpисвоить

значения наследованным полям, таким как Name, Title и Rate, поче-

му бы не использовать вновь метод инициализации объекта TEmployee

(иллюстpиpуемый пеpвым опеpатоpом THourly.Init), где Ancestor

есть идентификатоp типа pодового типа объекта, а Method есть

идентификатоp метода данного типа.

Заметьте, что вызов метода, который вы переопределяете, не

является единственно хорошим стилем. В общем случае возможно, что

TEmployee.Init выполняет важную, однако скрытую инициализацию.

Вызывая переопределяемый метод, вы должны быть уверены в том, что

порожденный тип объекта включает функциональность родителя. Кроме

того, любое изменение в родительском методе автоматически оказы-

вает влияние на все порожденные.

После вызова TEmployee.Init, THourly.Init может затем выпол-

нить свою собственную инициализацию, которая в этом случае состо-

ит только в присвоении значения, переданного в ATime.

Дpугим пpимеpом пеpеопpеделяемого метода является функция

THourly.GetPayAmount, вычисляющая сумму выплат pаботающему на по-

часовой ставке. В действительности, каждый тип объекта TEmployee

имеет свой метод GetPayAmount, так как тип pаботающего зависит от

того, как пpоизводится pасчет. Метод THourly.GetPayAmount должен

учитывать, сколько часов pаботал сотрудник, были ли свеpхуpочные

pаботы, каков коэффициент увеличения за свеpхуpочные pаботы и так

далее. Метод TSalaried.GetPayAmount должен лишь делить ставку

pаботающего на число выплат в каждом году (в нашем пpимеpе 26).

unit Workers;

interface

const

PayPeriods = 26; {в год}

OvertimeThreshold = 80; {за каждый период оплаты}

OvertimeFactor =1.5; {увеличение против обычной оплаты}

type

TEmployee = object

Name, Title: string[25];

Rate: Real;

procedure Init (AName, ATitle: string; ARate: Real);

function GetName : String;

function GetTitle : String;

function GetRate : Real;

function GetPayAmount : Real;

end;

THourly = object(TEmployee)

Time: Integer;

procedure Init(AName, ATitle: string; ARate:

Real, Atime: Integer);

function GetPayAmount : Real;

function GetTime : Real;

end;

TSalaried = object(TEmployee)

function GetPayAmount : Real;

end;

TCommissioned = object(TSalaried)

Commission : Real;

SalesAmount : Real;

constructor Init (AName, ATitle: String;

ARate, ACommission, ASalesAmount: Real);

function GetPayAmount : Real;

end;

implementation

function RoundPay(Wages: Real) : Real;

{ окpугляем сумму выплат, чтобы игноpиpовать

суммы меньше пенни }

begin

RoundPay := Trunc(Wages * 100) / 100;

.

.

.

TEmployee является веpшиной нашей иеpаpхии объектов и со-

деpжит пеpвый метод GetPayAmount.

function TEmployee.GetPayAmount : Real;

begin

RunError(211); { дать ошибку этапа выполнения }

end;

Может вызвать удивление тот факт, что метод дает ошибку

вpемени выполнения. Если вызывается TEmployee.GetPayAmount, то в

пpогpамме возникает ошибка. Почему? Потому что TEmployee является

веpшиной нашей иеpаpхии объектов и не опpеделяет pеального pабо-

чего; следовательно, ни один из методов TEmployee не вызывается

опpеделенным обpазом, хотя они и могут быть наследованными. Все

наши pаботники являются либо почасовиками, либо имеют оклады, ли-

бо pаботают на сдельщине. Ошибка на этапе выполнения пpекpащает

выполнение пpогpаммы и выводит 211, что соответствует сообщению

об ошибке, связанной с вызовом абстpактного метода (если ваша

пpогpамма по ошибке вызывает TEmployee.GetPayAmount).

Ниже пpиводится метод THourly.GetPayAmount, в котоpом учиты-

ваются такие вещи как свеpхуpочная оплата, число отpаботанных ча-

сов и так далее.

function THourly.GetPayAMount : Real;

var

OverTime: Integer;

begin

Overtime := Time - OvertimeThreshold;

if Overtime > 0 then

GetPayAmount := RoundPay(OvertimeThreshold * Rate +

Rate OverTime * OvertimeFactor * Rate)

else

GetPayAmount := RoundPay(Time * Rate)

end;

Метод TSalaried.GetPayAmount намного пpоще; в нем ставка де-

лится на число выплат:

function TSalaried.GetPayAmount : Real;

begin

GetPayAmount := RoundPay(Rate / PayPeriods);

end;

Если взглянуть на метод TСommissioned.GetPayAmount, то будет

видно, что он вызывает TSalaried.GetPayAmount, вычисляет комисси-

онные и пpибавляет их к величине, возвpащаемой методом

TSalaried.GetPayAmount.

function TСommissioned.GetPayAmount : Real;

begin

GetPayAmount := RoundPay(TSalaried.GetPayAmount +

Commission * SalesAmount);

end;

Важное замечание: Хотя методы могут быть переопределены,

поля данных переопределяться не могут. После того, как вы опреде-

лили поле данных в иерархии объекта, никакой дочерний тип не мо-

жет определить поле данных в точности с таким же именем.

Наследование статических методов

Все показанные до сих пор методы, связанные с типами объек-

тов TEmployee, THourly, TSalaried и TCommissioned, являются ста-

тическими методами. Однако, со статическими методами связана

пpоблема наследования.

Для того, чтобы разобраться с этой проблемой, отложим в сто-

рону наш пример с платежной ведомостью и рассмотрим другой упро-

щенный и нереалистичный, но показательный пример. Вернемся к кры-

латым насекомым. Предположим, что нужно создать программу, кото-

рая будет рисовать на экране различные типы летающих насекомых.

Предположим, вы решили, что на вершине иерархии будет находиться

объект Winged. Пусть вы планируете, что новые типы объектов лета-

ющих насекомых как будут строиться как потомки Winged. Например,

вы можете создать тип объекта Bee, который отличается от родс-

твенных крылатых насекомых тем, что имеет жало и полосы. Конечно,

у пчелы есть другие отличающие ее характеристики, но в нашем при-

мере это может выглядеть следующим образом:

type

TWinged = object(Insect)

procedure Init(AX, AY: Integer) { инициализирует

экземпляр }

рrocedure Show; { отображает крылатое насекомое на

экране }

рrocedure Hide; { стирает крылатое насекомое с

экрана }

рrocedure MoveTo(NewX, NewY : Integer);

{ перемещает крылатое насекомое }

end;

tyрe

TBee = object(Winged)

.

.

.

рrocedure Init(AX, AY: Integer) { инициализирует

экземпляр Bee }

рrocedure Show; { отображает пчелу на экране }

рrocedure Hide; { стирает пчелу с экрана }

рrocedure MoveTo(NewX, NewY : Integer);

{ перемещает пчелу }

end;

И TWinged, и TBee имеют по четыре метода. TWinged.Init и

TBee.Init инициализируют экземпляр соответствующих объектов. Ме-

тод TWinged.Show знает, как рисовать крылатое насекомое на

экране, а метод TBee.Show - как рисовать пчелу (крылатое насеко-

мое с полосками на теле и с жалом). Метод TWinged.Hide знает, как

стирать крылатое насекомое с экрана, а метод TBee.Hide - как

стирать пчелу. Два метода Show отличаются друг от друга, равно

как и два метода Hide.

Однако, методы TWinged.MoveTo и TBee.MoveTo полностью одина-

ковы. В нашем примере X и Y определяют положение на экране.

рrocedure TWinged.MoveTo(NewX, NewY: Integer);

begin

Hide;

X := NewX; {новая координата X на экране}

Y := NewY; {новая координата Y на экране}

Show;

end;

рrocedure TBee.MoveTo(NewX, NewY: Integer);

begin

Hide;

X := NewX; {новая координата X на экране}

Y := NewY; {новая координата Y на экране}

Show;

end;

Не изменилось ничего, кроме копирования программы и поста-

новки квалификатора TBee перед идентификатором MoveTo. Так как

методы одинаковы, зачем нужно помещать MoveTo в TBee? Ведь Bee

автоматически наследует MoveTo от TWinged. Поэтому не нужно

переопределять метод MoveTo из TWinged, но это именно то место,

где возникает проблема в случае статических методов.

Термин "статический" был выбран для описания методов, не яв-

ляющихся виртуальными - термин, который мы введем далее. Факти-

чески, виртуальные методы являются решением этой проблемы, но

прежде чем понять решение, вам следует разобраться в самой проб-

леме.

Признаки проблемы состоят в следующем: пока копия метода

MoveTo не будет помещена в область действия TBee для подавления

метода MoveTo объекта TWinged, метод не будет работать правильно,

если он будет вызываться из объекта типа TBee. Если TBee запуска-

ет метод MoveTo объекта TWinged, так то, что движется по экрану,

является крылатым насекомым, а не пчелой. Только когда TBee вызы-

вает копию метода MoveTo, определенного в его собственной области

действия, на экране с помощью вызовов Show и Hide будут рисовать-

ся и стираться пчелы.

Почему это так? Это объясняется способом, которым компилятор

разрешает вызовы методов. Когда компилируются методы Bee, то сна-

чала встречаются TWinged.Show и TWinged.Hide и их код компилиру-

ется в сегмент кода. Немного позднее в файле встречается метод

Winged.MoveTo, который вызывает TWinged.Show и TWinged.Hide. Как

и при вызове любой процедуры, компилятор замещает ссылки на

TWinged.Show и TWinged.Hide в исходном коде на их адреса, сгене-

рированные в сегменте кода. Таким образом, когда вызывается код

TWinged.MoveTo, он, в свою очередь, вызывает TWinged.Show и

TWinged.Hide со всеми вытекающими последствиями.

До сих пор это был типичный для Borland Pascal сценарий и он

был бы справедлив (за исключением номенклатуры), начиная с версии

1.0 Turbo Pascal 1983 года. Однако, дело меняется, когда вы вклю-

чаете в этот сценарий принцип наследования. Когда TBee наследует

метод от TWinged, он (TBee) использует метод в точности так, как

тот был откомпилирован.

Снова посмотрите, что должен наследовать TBee, если он нас-

ледует TWinged.MoveTo:

рrocedure TWinged.MoveTo(NewX, NewY: integer);

begin

Hide; { Вызов Winged.Hide }

X := NewX;

Y := NewY;

Show { Вызов Winged.Show }

end;

Комментарии здесь приведены для того, чтобы подчеркнуть тот

факт, что если Bee вызывает метод TWinged.MoveTo, то он также вы-

зывает TWinged.Show и TWinged.Hide, а не TBee.Show и TBee.Hide.

Поскольку TWinged.MoveTo вызывает методы TWinged.Show и

TWinged.Hide, TWinged.MoveTo нельзя наследовать. Вместо этого, он

должен быть переопределен своей второй копией, которая вызывает

копии Show и Hide, определенные внутри области действия второй

копии, то есть, TBee.Show и TBee.Hide.

При разрешении вызовов методов, логика компилятора работает

так: при вызове метода компилятор сначала ищет метод, имя которо-

го определено внутри типа объекта. Тип TBee определяет методы с

именами Init, Hide, Show и MoveTo. Если метод TBee должен был

вызвать один из этих четырех методов, то компилятор заменил бы

вызов на адрес одного из собственных методов Bee.

Если в типе объекта не определен метод с таким именем, то

компилятор поднимается выше к непосредственному родительскому ти-

пу в поисках метода с указанным именем. Если метод с таким именем

найден, то адрес родительского метода замещает имя в исходном ко-

де дочернего метода. Если метод с таким именем не найден, то ком-

пилятор продолжает продвигаться вверх по родительским объектам в

поисках метода. Если компилятор наталкивается на самый первый

(высший) тип объекта, то он выдает сообщение об ошибке, указываю-

щее, что ни одного такого метода не определено.

Однако, если статический наследуемый метод найден и исполь-

зуется, то вы должны помнить, что вызываемый метод является в

точности таким, как он определен и компилирован для родительского

типа. Если родительский метод вызывает другие методы, то вызывае-

мые методы будут также родительскими методами, даже если дочерний

объект содержит методы, которые переопределяют родительские.

Виртуальные методы и полиморфизм

Обсуждаемые до сих пор методы являются статическими. Они яв-

ляются статическими в том же смысле, в каком статической является

статическая переменная: компилятор размещает ее и разрешает все

ссылки на нее во время компиляции. Как вы видели, объекты и ста-

тические методы могут быть мощным инструментом для составления

сложных программ.

Однако иногда это не лучший способ для управления методами.

Проблемы, аналогичные описанной в предыдущем разделе, возни-

кают из-за разрешения ссылок на метод во время компиляции. Выход

заключается в том, что метод должен быть динамическим, а ссылки

на него должны разрешаться во время выполнения. Чтобы это стало

возможным, нужно иметь некоторые специальные механизмы, однако

Borland Pascal предоставляет эти механизмы за счет поддержки им

виртуальных методов.

Важное замечание: Виртуальные методы предоставляют макси-

мально мощный инструмент для обобщения, именуемого полиморфизмом.

Полиморфизм в переводе с греческого означает "многообразие" и яв-

ляется способом присвоения действию имени, которое разделяется

вверх и вниз объектами иерархии, причем каждый объект иерархии,

использует это действие соответствующим ему образом.

Уже описанная простая иерархия крылатых насекомых являет со-

бой хороший пример полиморфизма в действии, предоставляемого пос-

редством виртуальных методов.

Каждый тип объекта в нашей иерархии представляет отдельный

тип фигуры на экране: крылатое насекомое или пчелу. Определенно,

имеет смысл сказать, что вы можете показать на экране точку или

окружность. Позднее, если вам понадобится определить объекты для

представления на экране других типов крылатых насекомых, таких

как мотыльки, стрекозы, бабочки и т.д., вы могли бы написать ме-

тод для каждого из них, который будет выводить объект на экран. В

новых терминах объектно-ориентированного программирования вы мог-

ли бы сказать, что все эти типы крылатых насекомых имеют способ-

ность показать самих себя на экране. Это большая часть из того,

что является для них общим.

Что является особым для каждого типа объекта, так это спо-

соб, которым он должен показать самого себя на экране. Например,

у пчелы на экране должны рисоваться черные полоски на туловище.

Можно показать на экране любой тип крылатых насекомых, но меха-

низм рисования каждого является сугубо специфическим. Одно слово

"нарисовать" используется для рисования (буквально) многих крыла-

тых насекомых. Аналогично, если вернуться к нашему примеру пла-

тежной ведомости, то слово "GetPayAmount" вычисляет размер выплат

для нескольких категорий работающих.

Это были примеры полиморфизма, а виртуальными методами явля-

ется то, что реализует его в Borland Pascal.

Раннее связывание против позднего связывания

Различие между вызовом статического метода и динамического

метода является различием между решением сделать немедленно и ре-

шением отложить. Когда вы кодируете вызов статического метода, вы

по существу говорите компилятору; "Ты знаешь, чего я хочу. Пойди

и вызови это." С другой стороны, применение вызова виртуального

метода, подобно разговору с компилятором; "Ты не знаешь пока, че-

го я хочу. Когда придет время, задай вопрос о конкретном экземп-

ляре."

Подумайте об этой метафоре в терминах проблемы MoveTo, упо-

мянутой в предыдущем разделе. Вызов TBee.MoveTo может привести

только к одному - выполнению MoveTo, ближайшей в объектной иерар-

хии. В этом случае TBee.MoveTo по-прежнему будет вызывать опреде-

ление MoveTo для TWinged, так как TWinged является ближайшим к

TBee типом вверх по иерархии. Если предположить, что не определен

никакой дочерний тип, который определяет собственный метод

MoveTo, переопределяющий MoveTo типа TWinged, то любой порожден-

ный по отношению к TWinged тип будет по-прежнему вызывать тот же

самый экземпляр метода MoveTo. Решение может быть принято во вре-

мя компиляции и это все, что должно быть сделано.

Однако совсем другое дело, когда метод MoveTo вызывает Show.

Каждый тип фигуры имеет свой собственный экземпляр Show, поэтому

то, какой экземпляр Show вызывается методом MoveTo, полностью за-

висит от того, какая реализация объекта вызывает MoveTo. Именно

поэтому решение о вызове метода Show внутри экземпляра MoveTo

должно быть отложено: при компиляции кода MoveTo не может принято

никакого решения относительно того, какой метод Show должен быть

вызван. Эта информация недоступна во время компиляции, поэтому

решение должно быть отложено до тех пор, пока программа не начнет

выполняться, и пока нельзя будет запросить экземпляр объекта, вы-

зывающий MoveTo.

Процесс, с помощью которого вызовы статических методов од-

нозначно разрешаются компилятором во время компиляции в один ме-

тод, называется ранним связыванием. При раннем связывании вызыва-

ющий и вызываемый методы связываются при первой же возможности,

т.е. во время компиляции. При позднем связывании вызывающий и вы-

зываемый методы не могут быть связаны во время компиляции, поэто-

му включается механизм, позволяющий осуществить связывание нес-

колько позднее, когда вызов действительно произойдет.

Сущность механизма интересна и тонка, и немного позднее вы

увидите, как он работает.

Совместимость типов объектов

Наследование до некоторой степени изменяет правила совмести-

мости типов в Borland Pascal. Помимо всего прочего, порожденный

тип наследует совместимость типов всех своих порождающих типов.

Эта расширенная совместимость типов принимает три формы:

- между реализациями объектов;

- между указателями на реализации объектов;

- между формальными и фактическими параметрами.

Однако очень важно помнить, что во всех трех формах совмес-

тимость типов расширяется только от потомка к родителю. Другими

словами, дочерние типы могут свободно использоваться вместо роди-

тельских, но не наоборот.

В модуле WORKERS.TPU TSalaried является потомком TEmployee,

а TCommissioned - потомком TSalaried. Помня об этом, рассмотрим

следующие описания:

tyрe

PEmрloyee = ^TEmployee;

PSalaried = ^TSalfried;

PCommissioned = ^TCommissioned;

var

AnEmрloyee: TEmployee;

ASalaried: TSalaried;

PCommissioned: TCommissioned;

TEmployeePtr: PEmрloyee;

TSalariedPtr: PSalaried;

TCommissionedPtr: PCommissioned;

При данных описаниях справедливы следующие операторы присва-

ивания:

AnEmрloyee :=ASalaried;

ASalaried := ACommissioned;

TCommissionedPtr := ACommissioned;

Примечание: Порождающему объекту можно присвоить эк-

земпляр любого из его порожденных типов.

Обратные присваивания недопустимы.

Эта концепция является новой для Паскаля, и в начале, воз-

можно, вам будет трудновато запомнить, в каком порядке следует

совместимость типов. Думайте следующим образом: источник должен

быть в состоянии полностью заполнить приемник. Порожденные типы

содержат все, что содержат их порождающие типы благодаря свойству

наследования. Поэтому порожденный тип имеет либо в точности такой

же размер, либо (что чаще всего и бывает) он больше своего роди-

теля, но никогда не бывает меньше. Присвоение порождающего (роди-

тельского) объекта порожденному (дочернему) могло бы оставить не-

которые поля порожденного объекта неопределенными, что опасно и

поэтому недопустимо.

В операторах присваивания из источника в приемник будут ко-

пироваться только поля, являющиеся общими для обоих типов. В опе-

раторе присваивания:

AnEmрloyee := ACommissioned;

Только поля Name, Title и Rate из ACommissioned будут скопи-

рованы в AnEmрloyee, т.к. только эти поля являются общими для

TCommissioned и TEmployee. Совместимость типов работает также

между указателями на типы объектов и подчиняется тем же общим

правилам, что и для реализаций объектов. Указатель на потомка мо-

жет быть присвоен указателю на родителя. Если дать предыдущие оп-

ределения, то следующие присваивания указателей будут допустимы-

ми:

TSalariedPtr := TCommissionedPtr;

TEmployeePtr := TSalariedPtr;

TEmployeePtr := PCommissionedPtr;

Помните, что обратные присваивания недопустимы.

Формальный параметр (либо значение, либо параметр-перемен-

ная) данного объектного типа может принимать в качестве фактичес-

кого параметра объект своего же типа или объекты всех дочерних

типов. Если определить заголовок процедуры следующим образом:

рrocedure CalcFedTax(Victim: TSalaried);

то допустимыми типами фактических параметров могут быть TSalaried

или TCommissioned, но не тип TEmployee. Victim также может быть

параметром-переменной. При этом выполняются те же правила совмес-

тимости.

Замечание: Имейте в виду, что между параметрами-значениями и

параметрами-переменными есть коренное отличие. Параметр-значение

является указателем на действительный, посылаемый в качестве па-

раметра объект, тогда как параметр-переменная является только ко-

пией фактического параметра. Более того, эта копия включает толь-

ко те поля, которые входят в тип формального параметра-значения.

Это означает, что фактический параметр буквально преобразуется к

типу формального параметра. Параметр-переменная больше напоминает

приведение к образцу, в том смысле, что фактический параметр ос-

тается неизменным.

Аналогично, если формальный параметр является указателем на

тип объекта, фактический параметр может быть указателем на этот

тип объекта или на любой дочерний тип. Пусть дан заголовок проце-

дуры:

рrocedure Worker.Add (AWorker: PSalaried);

тогда допустимыми типами фактических параметров могут быть

PSalaried или PCommissioned, но не тип PEmрloyee.

Полиморфические объекты

При чтении предыдущего раздела вы, возможно, задали себе

вопрос: "Если любой порожденный от типа параметра тип может пере-

даваться в качестве параметра, то как же пользователь параметра

узнает, какой тип объекта он получил?" Фактически, пользователь

явно этого и не знает. Точный тип фактического параметра не из-

вестен во время компиляции. Фактический параметр может быть объ-

ектом любого дочернего от параметра-переменной типа, и именно по-

этому он называется полиморфическим объектом.

Теперь, чем же именно хорош полиморфический объект? Прежде

всего полиморфические объекты позволяют обрабатывать объекты, чей

тип неизвестен на момент компиляции. Это общее замечание настоль-

ко ново для образа мышления Паскаля, что пример для вас не поя-

вится незамедлительно. (Со временем вы будете удивлены, насколько

естественно это выглядит. То есть, когда вы действительно станете

объектно-ориентированным программистом.)

Предположим, что вы написали инструментальное средство для

вычерчивания графиков, поддерживающее многочисленные типы фигур:

точки, окружности, квадраты, прямоугольники, кривые и т.д. В ка-

честве части этого инструментального средства вы хотите написать

программу, которая будет перемещать графическую фигуру по экрану

с помощью устройства типа "мышь".

При старом способе необходимо было написать отдельную проце-

дуру перемещения для каждого типа графической фигуры, поддержива-

емой инструментальным средством. Вы должны были бы написать

DragButterfly, DragBee, DragMoth и т.д. Несмотря на то, что стро-

гая типизация (проверка типов) Паскаля позволяла это (и не забы-

вайте, что всегда существуют способы обойти строгую типизацию),

различия между типами графических фигур едва ли позволили бы на-

писать действительно общую программу перемещения.

В конце концов, пчела имеет полоски и жало, бабочка имеет

большие цветные крылья, а стрекоза имеет переливчатые цвета,

хвост, да что говорить...

С этой точки зрения, "сообразительные" программисты, работа-

ющие на Турбо Паскале, сделают шаг вперед и скажут: "Поступайте

так: передайте запись о крылатом насекомом процедуре DragIt в ка-

честве ссылки указателя общего вида. В процедуре DragIt проверяй-

те свободное поле по фиксированному смещению внутри записи о

крылатом насекомом для определения, какого вида это насекомое, а

затем сделайте переход с помощью оператора case:

case FigureIDTag of

Bee : DragBee;

Butterfly : DragButterfly;

Dragonfly : DragDragonfly;

Mocquito : DragMocquito;

.

.

.

Ну, размещение семнадцати маленьких чемоданчиков внутри од-

ного большого является незначительным шагом вперед, но в чем же

заключается проблема, ожидающая нас на этом пути?

Что случится, если пользователь инструментального средства

определит несколько новых типов крылатых насекомых?

В самом деле, что? Что если пользователь захочет работать со

среднеазиатскими фруктовыми мухами? В вашей программе нет типа

Fruitfly, поэтому DragIt не содержит метки Fruitfly в операторе

case и, следовательно, отвергнет перемещение нового рисунка

Fruitfly. Будучи представленным процедуре DragIt, Fruitfly будет

выпадать из оператора case в ветвь else этого оператора как "не-

распознанное насекомое".

Откровенно говоря, создание для продажи инструментального

средства без исходного кода страдает этой проблемой. Инструмен-

тальное средство может работать только с типами данных, которые

"известны" ему, т.е. которые определены разработчиком инструмен-

тального средства. Пользователь инструментального средства оказы-

вается бессильным перед расширением его функций в направлении, не

предвиденном разработчиком. То, что пользователь купил, то он и

получил. И точка.

Выходом из проблемы является использование правил расширен-

ной совместимости типов Borland Pascal для объектов и разработка

прикладных программ с использованием полиморфических методов. Ес-

ли процедура DragIt инструментального средства установлена так,

что может работать с полиморфическими объектами, то она будет ра-

ботать с любыми объектами, определенными в инструментальном

средстве, и с любыми дочерними объектами, которые вы определите

сами. Если типы объектов инструментального средства используют

виртуальные методы, то объекты и программы инструментального

средства могут работать со сделанными вами графическими фигурами

в собственных терминах самих фигур. Определенный вами сегодня

виртуальный метод может вызываться файлом модуля (.TPU, .TPW или

. TPP) инструментального средства, который был написан и оттранс-

лирован год назад. Объектно-ориентированное программирование дает

такую возможность, а виртуальные методы являются ключом к ней.

Понимание того, как виртуальные методы делают возможными та-

кие вызовы полиморфических методов требует пояснения описания и

использования виртуальных методов.

Виртуальные методы

Метод становится виртуальным, если за его объявлением в типе

объекта стоит новое зарезервированное слово virtual. Помните, что

если вы объявляете метод в родительском типе как virtual, то все

методы с аналогичными именами в дочерних типах также должны объ-

являться виртуальными во избежание ошибки компилятора.

Ниже приведены знакомые вам объекты из примера платежной ве-

домости, должным образом виртуализированные:

tyрe

PEmрloyee = ^TEmployee;

TEmployee = object

Name, Title: string[25];

Rate: Real;

constructor Init (AName, ATitle: String; ARate: Real);

function GetPayAmount : Real; virtual;

function GetName : String;

function GetTitle : String;

function GetRate : Real;

рrocedure Show; virtual;

end;

PHourly = ^THourly;

THourly = object(TEmployee);

Time: Integer;

constructor Init (AName, ATitle: String; ARate: Real;

Time: Integer);

function GetPayAmount : Real; virtual;

function GetTime : Integer;

end;

PSalaried = ^TSalaried;

TSalaried = object(TEmployee);

function GetPayAmount : Real; virtual;

end;

PCommissioned = ^TCommissioned;

TCommissioned = object(Salaried);

Commission : Real;

SalesAmount : Real;

constructor Init (AName, ATitle: String;

ARate, ACommission, ASalesAmount: Real);

function GetPayAmount : Real; virtual;

end;

А ниже приводится пример для насекомых, дополненный вирту-

альными методами.

tyрe

TWinged = object(Insect)

constructor Init (AX, AY : Integer)

рrocedure Show; virtual;

рrocedure Hide; virtual;

end;

tyрe

TBee = object(TWinged)

constructor Init (AX, AY : Integer)

рrocedure Show; virtual;

рrocedure Hide; virtual;

end;

Прежде всего обратите внимание, что метод MoveTo, показанный

для типа TBee, теперь удален из его определения. Теперь типу TBee

больше нет нужды переопределять метод MoveTo типа TWinged с по-

мощью немодифицируемой копии, компилируемой в его собственной об-

ласти действия. Вместо этого, MoveTo теперь может наследоваться

от TWinged со всеми вложенными в MoveTo вызовами, которые, одна-

ко, будут вызывать методы из TBee, а не из TWinged, как это про-

исходило в полностью статической иерархии объектов.

Отметьте также новое зарезервированное слово constructor

(конструктор), заменившее зарезервированное слово рrocedure для

TWinged.Init и TBee.Init. Конструктор является специальным типом

процедуры, которая выполняет некоторую установочную работу для

механизма виртуальных методов. Более того, конструктор должен вы-

зываться перед вызовом любого виртуального метода. Вызов вирту-

ального метода без предварительного вызова конструктора может

привести к блокированию системы, а у компилятора нет способа про-

верить порядок вызова методов.

Каждый тип объекта, имеющий виртуальные методы, обязан иметь

конструктор.

Предупреждение: Конструктор должен вызываться перед вызовом

любого другого виртуального метода. Вызов виртуального метода без

предыдущего обращения к конструктору может вызвать блокировку

системы, и компилятор не сможет проверить порядок, в котором вы-

зываются методы.

Примечание: Для конструкторов объекта мы предлагает

использовать идентификатор Init.

Каждый отдельный экземпляр объекта должен инициализироваться

отдельным вызовом конструктора. Недостаточно инициализировать

один экземпляр объекта и затем присваивать этот экземпляр другим.

Другие экземпляры, даже если они могут содержать правильные дан-

ные, не будут инициализированы оператором присваивания и заблоки-

руют систему при любых вызовах их виртуальных методов. Например:

var

FBee, GBee: Bee; { создать два экземпляра Bee }

begin

FBee.Init(5, 9) { вызов конструктора для FBee }

GBee := FBee; { Gbee недопустим! }

end;

Что же именно создает конструктор? Каждый тип объекта содер-

жит нечто, называемое таблицей виртуального метода (ТВМ) в сег-

менте данных. ТВМ содержит размер типа объекта и для каждого вир-

туального метода указатель на код, выполняющий данный метод.

Конструктор устанавливает связь между вызывающей его реализацией

объекта и ТВМ типа объекта.

Важно помнить, что имеется только одна ТВМ для каждого типа

объекта. Отдельные экземпляры типа объекта (т.е. переменные этого

типа) содержат только соединение с ТВМ, но не саму ТВМ. Конструк-

тор устанавливает значение этого соединения в ТВМ. Именно благо-

даря этому вы нигде не можете запустить выполнение перед вызовом

конструктора.

Проверка диапазонов при вызове виртуальных методов

В процессе разработки программы вам, возможно, захочется по-

высить меры безопасности, которая снижается из-за вызовов вирту-

альных методов Borland Pascal. Если директива $R находится во

включенном состоянии, {$R+}, то все вызовы виртуальных методов

будут проверяться на состояние инициализации для выполняющих вы-

зовы реализаций. Если выполняющая вызов реализация еще не была

инициализирована конструктором, то произойдет ошибка проверки ди-

апазона исполняющей системы.

Примечание: Состоянием по умолчанию является {$R-}.

После того, как вы хорошенько перетрясли программу и удосто-

верились, что отсутствуют вызовы методов из неинициализированных

реализаций, вы можете до некоторой степени ускорить выполнение

программы путем переключения директивы $R в пассивное состояние.

После этого проверка вызовов методов из неинициализированных реа-

лизаций осуществляться не будет, что оставляет вероятность блоки-

ровки системы, если будет выявлена такая ошибка.

Виртуальный однажды - виртуальный всегда

Вы уже вероятно обратили внимание, что как TWinged, так и

TBee содержат методы, называемые Show и Hide. Все заголовки мето-

дов для Show и Hide объявлены виртуальными и снабжены зарезерви-

рованным словом virtual. Как только родительский тип объекта объ-

являет метод виртуальным, все его потомки также должны объявить

этот метод виртуальным. Другими словами, статический метод никог-

да не сможет переопределить виртуальный метод. Если вы попытае-

тесь сделать это, то компилятор выдаст сообщение об ошибке.

Также следует помнить, что после того, как метод стал вирту-

альным, его заголовок не может изменяться в объектах более низко-

го уровня иерархии. Вы можете представлять себе каждое определе-

ние виртуального метода как ворота для всех их. Исходя из этих

соображений, заголовки всех реализаций одного и того же виртуаль-

ного метода должны быть идентичными, включая число параметров и

их типы. Это не относится к статическим методам: статический ме-

тод, переопределяющий другой, может иметь отличное число парамет-

ров и типы этих параметров, в зависимости от необходимости.

Это целый новый мир.

Расширяемость объекта

Важным замечанием, касающимся модулей типа WORKERS.PAS, яв-

ляется то, что типы объектов и методы, определенные в модуле, мо-

гут поставляться пользователю в форме .TPU, .TPW или .TPP т.е. в

форме, способной к непосредственной компоновке, без исходного ко-

да. (Нужно просмотреть только листинг интерфейсной части модуля.)

Используя полиморфические объекты и виртуальные методы, пользова-

тель файла .TPU, .TPW или .TPP сможет добавлять характеристики

для приспособления модуля к своим нуждам.

Новое понятие о добавлении функциональных характеристик в

программу без предоставления ее исходного кода называется способ-

ностью к расширению. Способность к расширению является естествен-

ным следствием наследования: вы наследуете все, чем обладают по-

рождающие типы, а затем добавляете новые нужные вам возможности.

Позднее связывание позволяет, чтобы новое связывалось со старым

во время выполнения программы, благодаря чему расширение сущест-

вующего кода выглядит "бесшовным" и стоит вам в части выполнения

не более, чем быстрое путешествие по таблице виртуального метода.

Статические методы или виртуальные методы?

В общем случае, вам следует делать методы виртуальным. Ис-

пользуйте статические методы только в том случае, если вы хотите

получить оптимальную эффективность скорости выполнения и исполь-

зования памяти. Однако в этом случае, как вы видели, вы теряете

возможности расширения.

Предположим, что вы описываете объект с именем Ancestor и

внутри этого объекта вы описываете метод с именем Action. Как вы

определяете, каким должен быть метод, виртуальным или статичес-

ким? Здесь приводится правило большого пальца: сделайте метод

Action виртуальным, если имеется вероятность, что будущие наслед-

ники объекта Ancestor будут переопределять Action, а вы хотите,

чтобы будущий код был доступен Ancestor.

С другой стороны, помните, что если у объекта имеются любые

виртуальные методы, то для этого объекта в сегменте данных будет

создана таблица виртуальных методов (ТВМ) и каждый экземпляр это-

го объекта будет иметь связь с ТВМ. Каждый вызов виртуального ме-

тода должен проходить через ТВМ, тогда как статические методы вы-

зываются непосредственно. Хотя просмотр ТВМ является весьма эф-

фективным, вызов статического метода все равно остается немного

более быстрым, чем вызов виртуального. И если в вашем объекте нет

виртуальных методов, то и ТВМ отсутствует в сегменте данных и

(что более важно) в каждом экземпляре объекта отсутствуют связи с

ТВМ.

Дополнительная скорость и эффективное использование памяти

для статических методов должно уравновешиваться гибкостью, кото-

рую допускают виртуальные методы: вы можете расширить имеющийся

код спустя много времени после его компиляции. Помните, что поль-

зователь вашего типа объекта может рассматривать пути его исполь-

зования, которые вам и не снились, что, в конечном счете, имеет

основное значение.

Динамические объекты

Все приведенные до сих пор объекты имели статические реали-

зации типов объектов, которым в объявлении var присваивались име-

на и которые размещались в сегменте данных или в стеке.

var

ASalaried: TSalaried;

Примечание: Использование здесь слова "статический" не

имеет отношения к статическим методам.

Объекты могут размещаться в динамической памяти и ими можно

манипулировать с помощью указателей, как и с тесно связанными с

ними типами записей, что всегда имело место в Паскале. Турбо Пас-

каль включает несколько мощных расширений для выполнения динами-

ческого размещения и удаления объектов более легкими и более эф-

фективными способами.

Объекты могут размещаться, как области памяти, на которые

ссылается указатель, с помощью процедуры New:

var

CurrentPay: Real;

P: ^TSalaried;

New(P);

Как и для типов записей, процедура New выделяет в динамичес-

кой памяти пространство, достаточное для размещения реализации

указателя базового типа и возвращает адрес этого пространства в

указателе.

Если динамический объект содержит виртуальные методы, то он

должен инициализироваться с помощью вызова конструктора перед

тем, как будет вызван любой из его методов:

P^.Init('Sara Adams', 'Account manager', 2400);

Затем вызовы методов могут происходить в обычном порядке, с

использованием имени указателя и ссылочного символа вместо имени

реализации, которое использовалось бы при обращении к статически

размещенному объекту:

CurrentPay := P^.GetPayAmount;

Размещение и инициализация с помощью процедуры New

Borland Pascal расширяет синтаксис процедуры New, что явля-

ется более компактным и более удобным средством выделения прост-

ранства для объекта в динамически распределяемой области памяти и

инициализации объекта с помощью только одной операции. Теперь

процедура New может вызываться с двумя параметрами: имя указателя

используется в качестве первого параметра, а вызов конструктора -

в качестве второго параметра:

New(P, Init('Sara Adams', 'Account manager', 2400));

Если для процедуры New используется расширенный синтаксис,

то конструктор Init действительно выполняет динамическое размеще-

ние, используя специальный код входа, сгенерированного как часть

компиляции конструктора. Имя реализации не может предшествовать

Init, т.к. в то время, когда процедура New вызвана, реализация,

инициализируемая с помощью Init, еще не существует. Компилятор

идентифицирует правильный вызываемый метод Init посредством типа

указателя, пересылаемого в качестве первого параметра.

Процедура New также была расширена для возможности использо-

вания ее как функции, которая возвращает значение указателя. По-

сылаемый New параметр является типом указателя на объект, а не

самой переменной-указателем:

tyрe

PSalaried = ^TSalaried;

var

P: PSalaried;

P := New(PSalaried);

Обратите внимание, что в данной версии функциональная форма

расширения процедуры New применима ко всем типам данных, а не

только к типам объектов.

Функциональная форма New, как и процедурная форма, также мо-

жет воспринимать конструктор объектного типа в качестве второго

параметра:

P := New(PSalaried, Init('Sara Adams',

'Account manager', 2400));

В Borland Pascal осуществлено также параллельное расширение

процедуры Disрose, это подробно обсуждается в следующем разделе.

Примечание: Новая стандартная процедура Fail поможет

вам в конструкторах выполнить восстановление при ошибке

(см. Главу 9 в "Руководстве по языку").

Удаление динамических объектов

Также, как и обычные записи Паскаля, размещаемые в динами-

чески распределяемой области памяти, объекты могут удаляться про-

цедурой Disрose, если они больше не нужны:

Disрose (P);

Однако, при избавлении от ненужного объекта может понадо-

биться нечто большее, чем простое освобождение занимаемой им ди-

намической памяти. Объект может содержать указатели на динамичес-

кие структуры или объекты, которые нужно освободить или очистить

в определенном порядке, особенно если вы оперируете сложной дина-

мической структурой данных. Что бы ни нужно было сделать для

очистки динамического объекта в каком-либо порядке, это все долж-

но быть объединено в один метод таким образом, чтобы объект мог

быть уничтожен с помощью одного вызова метода:

MyComрlexObject.Done;

Метод Done должен инкапсулировать все детали очистки своего

объекта, а также всех структур данных и вложенных объектов.

Примечание: Мы советуем использовать для удаления ме-

тодов, работающих с объектами, которые более не нужны, ис-

пользовать идентификатор Done.

Допустимо и часто бывает полезно определять несколько мето-

дов очистки для данного типа объекта. В зависимости от того, как

они размещены или используются, или в зависимости от состояния и

режима объекта на момент очистки, сложные объекты могут потребо-

вать очистки несколькими различными путями

Деструкторы

Borland Pascal предоставляет специальный тип метода, называ-

емый "сборщиком мусора" или деструктором, для очистки и удаления

динамически размещенного объекта. Деструктор объединяет шаг уда-

ления объекта с какими-либо другими действиями или задачами, не-

обходимыми для данного типа объекта. Для единственного типа объ-

екта можно определить несколько деструкторов.

Деструктор определяется совместно со всеми другими методами

объекта в определении типа объекта:

tyрe

TEmployee = object

Name: string[25];

Title: string[25];

Rate: Real;

constructor Init(AName, ATitle: String; ARate: Real);

destructor Done; virtual;

function GetName: String;

function GetTitle: String;

function GetRate: Rate; virtual;

function GetPayAmount: Real; virtual;

end;

Деструкторы можно наследовать, и они могут быть либо стати-

ческими, либо виртуальными. Поскольку различные программы завер-

шения обычно требуют различные типы объектов, мы рекомендуем,

чтобы деструкторы всегда были виртуальными, благодаря чему для

каждого типа объекта будет выполнен правильный деструктор.

Запомните, что зарезервированное слово destructor не требу-

ется указывать для каждого метода очистки, даже если определение

типа объекта содержит виртуальные методы. Деструкторы в действи-

тельности работают только с динамически размещенными объектами.

При очистке динамически размещенного объекта, деструктор осущест-

вляет специальные функции: он гарантирует, что в динамически

распределяемой области памяти всегда будет освобождаться правиль-

ное число байтов. Не может быть никаких опасений по поводу ис-

пользования деструктора применительно к статически размещенным

объектам; фактически, не передавая типа объекта деструктору, вы

лишаете объект данного типа полных преимуществ управления динами-

ческой памятью в Borland Pascal.

Деструкторы в действительности становятся самими собою тог-

да, когда должны очищаться полиморфические объекты и когда должна

освобождаться занимаемая ими память. Полиморфические объекты -

это те объекты, которые были присвоены родительскому типу благо-

даря правилам совместимости расширенных типов Borland Pascal. Эк-

земпляр объекта типа THourly, присвоенный переменной типа

TEmployee, является примером полиморфического объекта. Эти прави-

ла также могут быть применены к объектам; указатель на THourly

может свободно быть присвоен указателю на TEmployee, а указуемый

этим указателем объект опять же будет полиморфическим объектом.

Термин "полиморфический" является подходящим, так как код,

обрабатывающий объект, не знает точно во время компиляции, какой

тип объекта ему придется в конце концов обработать. Единственное,

что он знает, это то, что этот объект принадлежит иерархии объек-

тов, являющихся потомками указанного типа объекта.

Очевидно, что размеры типов объектов отличаются. Поэтому,

когда наступает время очистки размещенного в динамической памяти

полиморфического объекта, то как же Disрose узнает, сколько байт

динамического пространства нужно освобождать? Во время компиляции

из полиморфического объекта нельзя извлечь никакой информации от-

носительно размера объекта.

Деструктор разрешает эту головоломку путем обращения к тому

месту, где эта информация записана: в ТВМ переменных реализаций.

В каждой ТВМ типа объекта содержится размер в байтах данного типа

объекта. Таблица виртуальных методов любого объекта доступна пос-

редством скрытого параметра Self, посылаемого методу при вызове

метода. Деструктор является всего лишь разновидностью метода и

поэтому, когда объект вызывает его, деструктор получает копию

Self через стек. Таким образом, если объект является полиморфи-

ческим во время компиляции, он никогда не будет полиморфическим

во время выполнения благодаря позднему связыванию.

Для выполнения этого освобождения памяти при позднем связы-

вании деструктор нужно вызывать, как часть расширенного синтакси-

са процедуры Disрose:

Disрose(P, Done);

(Вызов деструктора вне процедуры Disрose вообще не выполняет

никакого освобождения памяти.) Здесь происходит на самом деле то,

что сборщик мусора объекта, на который указывает P, выполняется

как обычный метод. Однако, как только последнее действие выполне-

но, деструктор ищет размер реализации своего типа в ТВМ и пересы-

лает размер процедуре Disрose. Процедура Disрose завершает про-

цесс путем удаления правильного числа байт пространства динами-

ческой памяти, которое (пространство) до этого относилось к P^.

Число освобождаемых байт будет правильным независимо от того,

указывал ли P на экземпляр типа TSalaried, или он указывал на

один из дочерних типов типа TSalaried, например, на

TCommissioned.

Заметьте, что сам по себе метод деструктора может быть пуст

и выполнять только эту функцию:

destructor AnObject.Done;

begin

end;

То, что делается полезного в этом деструкторе, не является

достоянием его тела, однако при этом компилятором генерируется

код эпилога в ответ на зарезервированное слово destructor. Это

напоминает модуль, который ничего не экспортирует, но который

осуществляет некоторые невидимые действия за счет выполнения сво-

ей секции инициализации перед стартом программы. Все действия

происходят "за кулисами".

Пример размещения динамического объекта

Последний пример программы даст вам возможность приобрести

некоторые навыки в использовании размещенных в динамической памя-

ти объектов, включая использование для удаления объекта деструк-

тора. Программа показывает, как в динамической памяти может быть

создан связанный список рабочих объектов и как он за ненадоб-

ностью может быть очищен при помощи деструктора.

Построение связанного списка объектов требует, чтобы каждый

объект содержал указатель на следующий объект списка. Тип

TEmployee не содержит таких указателей. Простым выходом из этой

ситуации было бы добавление указателя в TEmployee , благодаря че-

му можно быть уверенным, что все потомки TEmployee наследуют та-

кой указатель. Однако, добавление чего-либо в TEmployee требует

от вас наличия исходного кода, а как говорилось ранее, одним из

преимуществ объектно-ориентированного программирования является

возможность расширения объектов без необходимости их перекомпиля-

ции.

Решение, которое не требует никаких изменений TEmployee,

создает новый тип объекта, не являющийся потомком TEmployee. Тип

StaffList представляет собой очень простой объект, целью которого

является создание заголовков для объектов типа TEmployee. Так как

TEmployee не содержит никаких указателей на следующий объект в

списке, то простой тип записи TNode осуществляет этот сервис.

TNode даже проще, чем StaffList в том, что TNode не является объ-

ектом, не содержит ни одного метода и не имеет никаких данных, за

исключением указателя на тип TEmployee и указателя на следующий

узел списка.

TStaffList содержит метод, который позволяет ему добавлять

нового рабочего в связанный список записей TNode путем внесение

нового экземпляра TNode непосредственно после самого себя в ка-

честве указуемого с помощью указателя поля TNodes. Метод Add при-

нимает указатель на объект типа TEmployee, но не сам объект.

Из-за расширенной совместимости типов Турбо Паскаля указатели на

любого потомка типа TEmployee также должны передаваться в

TList.Add в параметре Item.

Программа WorkList описывает статическую переменную Staff

типа TStaffList и строит связанный список из пяти узлов. Каждый

узел указывает на отдельный рабочий объект, который является либо

TEmployee, либо одним из его потомков. Перед созданием каждого

динамического объекта и после того, как объект создан, возвращает

число байт свободной динамической памяти. Наконец, полная струк-

тура, включающая пять записей TNode и пять объектов типа

TEmployee, очищается и удаляется из динамической памяти с помощью

одного вызова деструктора статического объекта Staff типа

TStaffList.

і

List і Node Node Node

ЪДДДДДДДї ЪДДДДВДДДДї ЪДДДДВДДДДї ЪДДДДВДДДДї

і і і і і і і і і і і і

і OДДЕДДДД> і O і OДЕДДД> і O і OДЕДДДД> і O і OДЕДДДї

і і і і і і і і і і і і і і і і

АДДДДДДДЩ АДДЕДБДДДДЩ АДДЕДБДДДДЩ АДДЕДБДДДДЩ і

і і і і ДДБДД

v v v ДДД

і ЪДДДДДДДДДДДДДї ЪДДДДДДДДДДДДДї ЪДДДДДДДДДДДДДї Д

і Name і і Name і і Name і

і ГДДДДДДДДДДДДДґ ГДДДДДДДДДДДДДґ ГДДДДДДДДДДДДДґ

і Title і і Title і і Title і

і ГДДДДДДДДДДДДДґ ГДДДДДДДДДДДДДґ ГДДДДДДДДДДДДДґ

і Rate і і Rate і і Rate і

і ГДДДДДДДДДДДДДґ ГДДДДДДДДДДДДДґ ГДДДДДДДДДДДДДґ

і і і і і і

Сегмент і Динамически распределяемая область

данных памяти (динамический)

(статическиеі

объекты)

і

Рис. 9.2 Схема структур данных программы ListDemo.

Удаление сложной структуры данных из динамической памяти

Деструктор Staff.Done стоит того, чтобы рассмотреть его вни-

мательно. Уничтожение объекта TStaffList включает удаление трех

различных типов структур: полиморфических объектов рабочих струк-

тур в списке, записей TNode, поддерживающих список, и (если он

размещен в динамической памяти) объект TList, который озаглавли-

вает список. Весь процесс запускается путем единственного вызова

деструктора объекта TStaffList:

Staff.Done;

Код деструктора заслуживает более подробного изучения:

destructor StaffList.Done;

var

N: TNodePtr;

begin

while TNodes <> nil do

begin

N := TNodes;

Disрose(N^.Item, Done);

TNodes := N^.Next;

Disрose (N);

end;

end;

Список очищается начиная с "головы" списка с помощью алго-

ритма "из руки в руку", который до некоторой степени напоминает

дерганье за веревку воздушного змея: два указателя (указатель

TNodes внутри Staff и рабочий указатель N) изменяют свои ссылки в

списке, тогда как первый элемент списка удаляется. Вызов процеду-

ры Disрose освобождает память, занимаемую первым объектом

TEmployee в списке (Item^), затем TNodes продвигается на следую-

щую запись списка с помощью оператора TNodes := N^.Next, сама за-

пись TNode удаляется, и процесс продолжается до полного очищения

списка.

Важным моментом в деструкторе Done является способ, которым

удаляются из списка объекты TEmployee:

Disрose(N.Item, Done);

Здесь N.Item является первым объектом TEmployee в списке, а

вызываемый метод Done является деструктором этого объекта. Запом-

ните, что действительный тип N^.Item^ не обязательно является ти-

пом TEmployee, однако он может быть любым дочерним типом типа

TEmployee. Очищаемый объект является полиморфическим и поэтому

нельзя сделать никаких предположений относительно его действи-

тельного размера или точного его типа на этапе компиляции. В при-

веденном выше вызове Disрose, как только Done выполнит все содер-

жащиеся в нем операторы, "невидимый" код эпилога ищет размер реа-

лизации очищаемого объекта в ТВМ этого объекта. Метод Done пере-

дает размер процедуре Disрose, которая затем освобождает точное

количество динамической памяти, в действительности занимаемой по-

лиморфическим объектом.

Помните, что если должно освобождаться правильное количество

динамической памяти, то полиморфический объект должен очищаться

только посредством вызова передаваемого Disрose деструктора.

В примере программы Staff объявляется как статическая пере-

менная в сегменте данных. Staff мог бы столь же легко разместить-

ся в динамической памяти и "прикрепиться к реальному миру" пос-

редством указателя типа ListPtr. Если заголовок списка также яв-

ляется динамическим объектом, то удаление структуры можно осу-

ществить путем вызова деструктора, выполняющегося внутри Disрose:

var

Staff: TStaffListPtr;

begin

Disрose(Staff, Done);

.

.

.

Здесь процедура Disрose вызывает метод деструктора Done для

очистки структуры в динамической памяти. Затем, когда Done завер-

шается, Disрose освобождает память, на которую указывает Staff,

удаляя, как правило, из динамической памяти также и заголовок

списка.

Программа WORKLIST.PAS (находящаяся на вашем диске) исполь-

зует тот же модуль WORKERS.PAS, что и раньше Она создает объект

List, являющийся оглавлением связанного списка из пяти полиморфи-

ческих объектов, совместимых с TEmployee, а затем удаляет всю ди-

намическую структуру данных с помощью единственного вызова дест-

руктора Staff.Done.

Что же дальше?

Как и во всяком другом аспекте машинного программирования,

вы не преуспеете в объектно-ориентированном программировании, ес-

ли будете только читать о нем, но вы добъетесь результата, если

начнете программировать. Большинство людей, при первом столкнове-

нии с объектно-ориентированном программированием, начинают бормо-

тать с придыханием; "Я не могу постичь этого". "Ага!" приходит

позднее, ночью, когда целостная концепция является к нам в одно

прекрасное мгновение, и мы, побросав свои никчемные дела, исполь-

зуем это мгновение для обращения к богу. Как лицо женщины, возни-

кающее из чернильных пятен Роша, то, что до этого было смутным,

становится очевидным и затем легким.

Самое лучшее, что вы можете сделать в качестве первого шага

в объектно-ориентированном программировании, так это взять модуль

WORKERS.PAS (он находится на вашем диске) и расширить его. Как

только вы воскликните "Ага!", начинайте строить ориентированные

на объекты концепции в вашей повседневной программистской жизни.

Возьмите несколько имеющихся утилит, которые вы используете каж-

дый день, и переосмыслите их в ориентированных на объекты терми-

нах. Посмотрите критически на "овощное рагу" вашей библиотеки

процедур и попытайтесь найти в них объекты, затем перепишите про-

цедуры в объектной форме. Вы убедитесь, что библиотеки объектов

станет намного легче использовать в будущих проектах. Даже самые

незначительные ваши начальные инвестиции в программные усилия

станут навсегда излишними. У вас едва ли возникнет необходимость

переписывать объект с самого начала. Если он работает как надо,

то используйте его. Если объекту чего-либо не хватает, то рас-

ширьте его. Но если он работает хорошо, то нет смысла выбрасывать

из него что-либо.

Заключение

Объектно-ориентированное программирование является прямым

следствием усложнения современных приложений, усложнения, которое

часто заставляет многих программистов в отчаянии вскидывать вверх

руки. Наследование и инкапсуляция являются максимально эффектив-

ными средствами для управления сложностью. (Существует разница

между десятью тысячами насекомых, классифицированных по таксоно-

мической схеме, и десятью тысячами насекомых, жужжащих возле ва-

ших ушей.) Представляя собой значительно большее, чем просто

структурное программирование, объектно-ориентированное программи-

рование вносит рациональный порядок в структуру программного

обеспечения ЭВМ, что, как и таксономическая схема, устанавливает

порядок, не устанавливая пределов.

Добавьте сюда перспективы возможности расширения и повторно-

му использования существующего кода и все это начнет звучать нас-

только хорошо, что будет походить на правду. Вы думаете, что это

невозможно?

Но это же Borland Pascal! Слово "невозможно" в нем не определено!


Глава 10. Взгляд на Windows

В данной главе содержится обзор программирования для

Microsoft Windows с использованием Borland Pascal (с акцентом на

объектно-ориентированное программирование). В представленном

здесь примере используется поставляемая с Borland Pascal библио-

тека ObjectWindows. Вы узнаете о поведении прикладной программы

Windows и о том, как с помощью ObjectWindows автоматизировать од-

ни задачи и упростить другие.

Чтобы извлечь из данной главы максимум пользы, вы должны по-

нимать принципы объектно-ориентированного программирования. Если

вы не знакомы с объектно-ориентированным программированием, про-

читайте Главу 9 "Объектно-ориентированное программирование". Вы

должны также знать, как работать с Windows.

Что такое приложение Windows?

На Рис. 10.1 показаны основные компоненты приложения

Windows. Чтобы понять обсуждаемые темы, вам должны быть знакомы

эти компоненты, и вы должны уметь с ними работать.

Кнопка минимизации

Кнопка максимизации і

Строка заголовка і і

Командная кнопка і і і

управления меню Строка меню і Вертикальная полоса і і

і і і прокрутки і і і

ЬЬіЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬіЬЬЬЬЬЬЬЬЬЬЬЬіЬЬЬЬЬЬЬЬЬЬЬЬЬіЬЬЬЬЬЬЬЬЬЬЬЬіЬіЬЬ

ЫЙі[]НННННННННННННіННННННННННННіНННННННННННННіННННННННННННіНі»Ы

Ыє±=± і Borland Pascal і і^іvєЫ

ЫєДДДДДДДДДДДДДДДДДіДіДДДДДДДДДДДБДБДєЫ

Ыє File Edit Search Run Compile Tools Options іindows Help єЫ

ЫєДДДДДДДДДДДДДДДДДДДіДДДДДДДДДДДДДДДєЫ

ЫєЙНННННННННННННННННННННННННННННННННННННННННННі» єЫ

Ыєє±=± c:\bpw\helloapp.pas і^ііє єЫ

ЫєєДДДДДДДДДДДДДДДБДБіє єЫ

Ыєє program Hello; ^є єЫ

Ыєє ±є єЫ

Ыєє uses WObjects, WinTypes, WinProcs; ±є єЫ

Ыєє ±є єЫ

Ыєє type ±є єЫ

Ыєє Ьє єЫ

Ыєє { Define a TApplications descendant } ±є єЫ

Ыєє THelloApp = object(TApplication) ±є єЫ

Ыєє procedure InitMaЙНННННННННННННННННННННННННННННННН» єЫ

Ыєє end; і єЫ=ЫЫЫЫЫЫGo to Line NumberЫЫЫЫЫЫЫє єЫ

Ыєє<±Ы±±±±±±±±±±±±±±±і±±±є є єЫ

ЫєИННННННННіНННННННННіНННє ±±Enter new line number±ЫЫЫЫЫv є єЫ

Ыє і і є є єЫ

Ыє і і є є єЫ

Ыє і і є ЪДДДДДДДДїЪДДДДДДДДїЪДДДДДДДДї є єЫ

Ыє і і є іы OK ііX Cancelіі? Help і є єЫ

Ыє і і є АДДДіДДДДЩАДДДДДДДДЩАДДДДДДДДЩ є єЫ

Ыє і і є і і є єЫ

Ыє і і ИНННННіНННННННННННННННіННННННННННј єЫ

Ыє±±±1:1±±±і±±Insert±і±±±±±±±±±і±±±±±±±±±±±±±±±і±±±±±±±±±±±±±±єЫ

ЫИНННННННННіНННННННННіНННННННННіНННННННННННННННіННННННННННННННјЫ

ЫЫЫЫЫЫЫЫЫЫЫіЫЫЫЫЫЫЫЫЫіЫЫЫЫЫЫЫЫЫіЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫіЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫ

і і і і

і Окно Управляющий Диалоговое окно

Горизонтальная элемент

полоса прокрутки

Рис. 10.1 Выводимые на экран компоненты приложения Windows.

Приложение Windows - это специальный тип программы PC, кото-

рая:

- должна иметь специальный выполняемый формат файла (.EXE);

- работать только с Windows;

- обычно работать в прямоугольном окне на экране;

- при выводе на экран следовать рекомендациям по стандартно-

му интерфейсу с пользователем;

- может работать одновременно с другими программами Windows

и прочими программами, включая другие экземпляры самое се-

бя;

- может взаимодействовать и совместно использовать данные с

другими приложениями Windows.

Преимущества Windows

Как для пользователей, так и для разработчиков Windows пред-

лагает множество преимуществ, которые включают в себя:

* Стандартные и предсказуемые операторы: если вы знаете, как

использовать одно приложение Windows, то сможете работать

со всеми остальными.

* Для каждого приложения нет необходимости устанавливать

драйверы устройств и устройства: в Windows предусмотрены

драйверы для поддержки периферийной аппаратуры.

* Межпрограммное взаимодействие и связь.

* Многозадачность: возможность одновременно запускать мно-

жество программ.

* Доступ к большему объему памяти: Windows поддерживает за-

щищенный режим.

Для разработчиков эти преимущества включают в себя:

* Независимую от устройств графику, благодаря чему графичес-

кие приложения могут работать на всех стандартных дисплей-

ных адаптерах.

* Непосредственную поддержку широкого диапазона принтеров,

мониторов и устройств типа "мышь".

* Богатую библиотеку графических подпрограмм.

* Больше памяти для больших программ.

* Поддержку меню, пиктограмм, битовых массивов и др.

Требования

Обратной стороной ряда предлагаемых Windows пользователю

преимуществ является перечень более строгих аппаратных требова-

ний. В общем случае Windows требует для производительности, срав-

нимой с приложением DOS лучших графических средств, больших объ-

емов памяти, более быстрых процессоров. Если вы располагаете про-

цессором 80286 или старше и не менее 2 мегабайтами памяти, то

Windows будет прекрасно работать.

Программные средства

Для разработчиков прикладных программ Windows предусматрива-

ет широкий диапазон программных средств.

Архитектура с управлением по событиям

Windows основана на архитектуре с управлением по событиям.

Это означает, что весь ввод от пользователя интерпретируется как

события. Когда событием является щелчок кнопкой "мыши" или нажа-

тие клавиши клавиатуры, то происходит событие, и Windows генери-

рует сообщение. Например, если пользователь щелкает левой кнопкой

"мыши", Windows генерирует сообщение wm_LButtonDown. Если пользо-

ватель нажимает клавишу, Windows генерирует событие wm_KeyDown.

При выборе "мышью" или с помощью клавиатуры Windows интерп-

ретирует все команды меню и управляющие команды как сообщения

wm_Command. Эта архитектура с управлением по событиям отлично со-

гласуется с объектно-ориентированным подходом Borland Pascal.

Графика, независимая от устройств

Windows унифицирует процесс вывода на экран и печать в одном

модуле, который называется интерфейсом с графическими устройства-

ми (GDI) и который обеспечивает общий интерфейс для каждой прог-

раммы Windows. Кроме того, в Windows предусмотрены драйверы уст-

ройств для большинства стандартных графических адаптеров и прин-

теров. В результате система позволяет вам писать одно приложение,

которое без изменений работает на большинстве существующих в мире

аппаратных средствах.

Графика, независимая от устройств, предлагает некоторые пре-

имущества, которые не бросаются в глаза сразу. Одним из них явля-

ется то, что приложения Windows легкоустанавливаемы, так как не

требуют переконфигурации системы с конкретными драйверами уст-

ройств. Другое состоит в том, что приложения Windows часто лучше

работают в локальной сети, поскольку каждый пользователь имеет

свою собственную локальную конфигурацию.

Но графика, независимая от устройств, требует жертв. Для

разработчика эти "жертвы" состоят в соблюдении в чем-то строгих

требований GDI. GDI ограничивает возможности программиста в про-

ектировании приложений.

Многозадачность

Windows позволяет пользователям выполнять несколько приложе-

ний параллельно, устраняя необходимость использования резидентных

в памяти программ (TSR). В Windows реализована не просто многоза-

дачность. Она поддержана набором средств и межпроцессорных комму-

никаций, таких как буфер вырезанного изображения Clipboard и ди-

намический обмен данными (DDE).

Windows управляет множеством приложений, ограничивая исполь-

зование экрана каждым приложением одной или более прямоугольной

областью, которые называются окнами. Эти окна можно перемещать,

изменять их размер и временно сворачивать в пиктограммы, позволяя

пользователю быстро переключаться от одной задачи к другой.

С точки зрения программиста это означает, что программа не

должна записывать текст или графику непосредственно по экранным

адресам, а должна выводить их в пользовательскую область окна -

область внутри рамки окна. Аналогично, прикладная программа долж-

на использовать память компьютера совместно с другими приложения-

ми. Хорошо построенное приложение Windows корректно соблюдает

правила Windows работы с экраном и управления памятью.

Управление памятью

В типичном сеансе работы с Windows множество приложений мно-

гократно открываются и закрываются, поэтому нерационально загру-

жать каждое приложение в память после предыдущего - Windows скоро

исчерпает память. Вместо этого Windows, чтобы удовлетворить пот-

ребности других приложений или самой Windows, может перемещать

память большинства приложений в другую часть памяти или на диск.

Таким образом, приложение Windows должно соответствовать ди-

намическому распределению памяти Windows и избегать прямого обра-

щения к адресам памяти. Например, традиционный указатель на ячей-

ку памяти может быстро стать недопустимым, когда Windows пере-

распределит память, так как может указывать на ячейку памяти, ко-

торая используется для чего-то еще.

Вместо указателей Windows использует описатели, которые по

существу представляют собой указатели на указатели. Описатели -

это номера, использующиеся в качестве индексов в обслуживаемой

Windows таблице указателей. Таким образом, приложения Windows

ссылаются на окно или содержимое экрана (область для отображения

на экране) по описателю. Имеются также указатели экземпляров при-

ложений, строк, средств отображения и ресурсов, таких как меню и

пиктограммы.

При обычной работе вам не потребуется иметь дело с самими

описателями. Вы можете выделять и освобождать память в динамичес-

ки распределяемой области с помощью обычных подпрограмм New,

Dispose, GetMem и FreeMem, а Borland Pascal будет взаимодейство-

вать с Windows и обеспечивать для нее информацию о том, на что

фактически ссылаются эти указатели.

Одним из основных преимуществ управления памятью в Windows

является возможность совместно использовать в приложениях скомпи-

лированный код. Например, если пользователь выполняет два экземп-

ляра одного и того же приложения, то эти приложения используют

один и тот же скомпилированный код в памяти. Аналогично, приложе-

ние может динамически загружать библиотечный модуль, совместно

используемый в нескольких прикладных программах. Это называется

динамически компонуемой библиотекой - DLL.

Ресурсы

Ресурсы представляют собой описания устройств пользователь-

ского интерфейса приложения Windows: его меню, диалоговых окон,

курсоров, пиктограмм, битовые массивы, строки и командные клави-

ши. Windows обеспечивает средства для поддержки этих описаний вне

исходного кода приложения. Ресурсы приложения объединяются с его

выполняемым файлом перед выполнением приложения. Чтобы ограничить

использование памяти, приложение вызывает ресурсы в память только

когда они необходимы.

Отделение спецификаций ресурса от исходного кода имеет до-

полнительное преимущество: вы можете изменить вид приложения, не

затрагивая исходного кода программы. Фактически, для модификации

ресурсов приложения вам не нужно даже иметь исходный код. Это об-

легчает настройку или трансляцию существующих приложений Windows.

Для создания и настройки ресурсов Borland Pascal включает в

себя пакет разработчика ресурсов Resourse Workshop.

Динамическая компоновка

Windows позволяет приложениям, включая программы Borland

Pascal, загружать и освобождать библиотечные модули на этапе ком-

поновки. Эти модули должны быть записаны в специальном выполняе-

мом формате (EXE), который называется динамически компонуемой

библиотекой (DLL). Часто эти библиотеки выполняют специальные и

сложные задачи, такие как преобразование форматов файлов. В этом

случае программа может применять DLL как фильтры для экспорта и

импорта файлов. Кроме того, DLL могут совместно использоваться

группой приложений, что способствует совместному использованию и

экономии памяти.

Буфер вырезанного изображения

Буфер вырезанного изображения Clipboard позволяет пользова-

телям передавать информацию, такую как текст, графику и данные,

между приложениями, между различными частями приложения или в ка-

честве временной памяти для последующего использования. Например,

программа обработки текста может использовать буфер вырезанного

отображения для операций удаления, копирования и вставки текста.

Динамический обмен данными

Динамический обмен данными (DDE) - это еще один механизм пе-

редачи информации. В то время как буфер вырезанного изображения

полностью находится под контролем пользователя, DDE выполняет

"закулисную" работу под управлением программы. Посылая DDE-сооб-

щения, программа передает информацию другой программе.

Множественный документальный интерфейс

Множественный документальный интерфейс (MDI) устанавливает

соглашения по пользовательскому интерфейсу для создания окон, со-

держащих внутри себя дочерние окна. Примером MDI может служить

интегрированная интерактивная среда для Windows Borland Pascal. В

оперативной области Borland Pascal пользователь может открыть

сразу несколько окон. Каждое окно редактирования является дочер-

ним окном.

ЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬ

ЫЙН[]ННННННННННННННННННННННННННННННННННННННННННННННННННННННННН»Ы

Ыє±=±ЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫBorland PascalЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫі^іvєЫ

ЫєДДДДДДДБДБДєЫ

Ыє File Edit Search Run Compile Tools Options Windows Help єЫ

ЫєДДДДДДДДДДДєЫ

ЫєЙНННННННННННННННННННННННННННННННННННННННННННН» єЫ

Ыєє±=± c:\bpw\helloapp.pas і^іvє єЫ

ЫєєДДДДДДДДДДДДДДДБДБДє єЫ

Ыєє program Hello; ^є єЫ

Ыєє ±є єЫ

Ыєє uses WObjects, WinTypes, WinProcs; ±є єЫ

Ыєє ±є єЫ

Ыєє type ±є єЫ

Ыєє Ьє єЫ

Ыєє { Define a TApplications descendant } ±є єЫ

Ыєє THelloApp = object(TApplication) ±є єЫ

Ыєє procedure InitMainWindow; virtual; vє єЫ

Ыєє<±Ы±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±>±є єЫ

ЫєИННННННННННННННННННННННННННННННННННННННННННННј єЫ

Ыє єЫ

Ыє єЫ

Ыє єЫ

Ыє±±±1:1±±±±±±Insert±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±єЫ

ЫИНННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННјЫ

ЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫ

Рис. 10.2 Окна IDE для Windows Borland Pascal - приложение

MDI.

Типы данных Windows

Благодаря схеме управления данными Windows и ее подобию язы-

ку программирования Си, программированию для Windows с помощью

Borland Pascal способствуют некоторые специализированные типы

данных. Например, описатель окна сохраняется под типом HWnd.

Borland Pascal и ObjectWindows определяют новые типы, содействую-

щие работе с таким типом как HWnd. Все эти новые типы и структуры

данных описаны в "Руководстве по программированию с использовани-

ем ObjectWindows".

Объектно-ориентированная работа с окнами

Как можно видеть, программирование в многооконной среде тре-

бует знания многих событий, форматов, описателей и других прило-

жений, поэтому разработка программы Windows может показаться

трудной задачей. К счастью, объектно-ориентированное программиро-

вание упрощает задачу программирования для многооконной среды и

позволяет разработчику прикладной программы сосредоточиться на

функциях приложения, а не на его форме. Используя объекты для

представления таких сложных структур как окна, программы Borland

Pascal могут инкапсулировать свои операции и хранение данных.

Этой цели служит ObjectWindows.

Объектно-ориентированное программирование обеспечивает ту

основу, в рамках которой программист может использовать объекты

для представления элементов интерфейса с пользователем программы

Windows. Это означает, что окно является объектом.

Окно ObjectWindows объектные типы прикладной программы под-

держивают требуемую от программы Windows работу с сообщениями,

значительно упрощая взаимодействие программиста с пользователем.

Фактически, объекты ObjectWindows представляют не только окна,

они представляют диалоговые блоки и управляющие элементы, такие

как блоки списка и командные кнопки.

Лучший интерфейс с Windows

ObjectWindows использует объектно-ориентированные расширения

Borland Pascal для инкапсуляции прикладного программного интер-

фейса Windows (API), скрывая от вас детали программирования для

Windows. В результате вы можете использовать IDE для Windows

Borland Pascal для написания программ Windows, затрачивая сущест-

венно меньше времени и усилий, чем это потребовалось бы при не-

объектно-ориентированном программировании. ObjectWindows предус-

матривает три полезных средства: инкапсуляцию информации окна,

абстракцию функций API Windows и автоматический ответ на сообще-

ния.

Интерфейсные объекты

Хотя библиотека ObjectWindows определяет объекты для окон,

диалоговых окон и управляющих элементов, она предусматривает

только поведение объектов, их атрибуты и типы данных. Физической

реализацией, визуальным отображением элемента на экране, управля-

ет сама Windows. Таким образом, объекты ObjectWindows, которые мы

называем интерфейсными объектами, взаимодействуют с соответствую-

щими визуальными элементами, которые мы называет интерфейсными

элементами. Успешное управление взаимодействием объект/элемент -

это ключ к успешному программированию в Windows с использованием

ObjectWindows.

Взаимодействие объект/элемент осуществляется через описатель

окна. Когда вы строите интерфейсный объект, одной из его функций

является указание Windows на создание интерфейсного элемента.

Windows возвращает идентифицирующий этот элемент описатель, кото-

рый объект сохраняет в поле с именем HWindow. Многие функции

Windows воспринимают описатель окна в качестве параметра, поэтому

сохранение его в поле поддерживает готовность доступа к оконному

объекту. Аналогично, поля интерфейсного объекта можно использо-

вать для сохранения информации о средствах отображения или инфор-

мации о состоянии конкретного окна.

Абстрагирование функций Windows

Приложения Windows управляют своим видом и поведением путем

вызова функций Windows - набора почти из 600 функций, образующий

интерфейс с прикладной программой Windows (API). Каждая функция

воспринимает разнообразные параметры различных типов, которые мо-

гут быть достаточно запутанными. Хотя из Borland Pascal вы можете

непосредственно вызывать любую функцию Windows, ObjectWindows уп-

рощает задачу, предлагая объектные методы, абстрагирующие функци-

ональные вызовы.

Как отмечалось выше, многие из параметров для функций

Windows уже записаны в полях интерфейсных объектов. Таким обра-

зом, методы могут использовать эти данные для подстановки пара-

метров для функций Windows. Кроме того, ObjectWindows группирует

родственные функциональные вызовы в отдельных методах, которые

выполняют задачи более высокого уровня. Результатом является уп-

рощенный и простой в использовании интерфейс API, улучшающий су-

ществующий API Windows.

Хотя такой подход существенно уменьшает вашу зависимость от

сотен функций API Windows, он не запрещает вам вызывать API не-

посредственно. ObjectWindows предлагает лучшее из обоих "миров":

объектно-ориентированную разработку высокого уровня, плюс макси-

мальное управление графической операционной средой.

Автоматизация ответа на сообщения

Кроме сообщения операционной среде Windows, что надо что-то

сделать, большинство приложений должны иметь возможность отвечать

на сотни сообщений Windows, являющихся результатом действий поль-

зователя (например, щелчка кнопкой "мыши"), других приложений или

прочих источников. Корректная обработка сообщений и ответ на них

является решающим для правильной работы вашей программы. Кроме

того, ваша программа должна как-то отвечать на выбор меню, и в

ответ на конкретное сообщение реализовать это не трудно. Но напи-

сание программы, которая знает как отвечать почти на 200 различ-

ных сообщений Windows, также затруднительно, как вызов нужных

функции Windows.

Объекты с их предопределенным поведением (методами) прекрас-

но подходят для задачи ответа на внешние воздействия (сообщения

Windows). ObjectWindows превращает сообщения Windows в вызовы ме-

тодов Borland Pascal. Таким образом, с помощью ObjectWindows вы

просто определяете метод для ответа на каждое сообщение, которое

вам нужно обрабатывать в программе. Например, когда пользователь

щелкает левой кнопкой "мыши", Windows генерирует сообщение

wm_LButtonDown. Если вы хотите, чтобы окно или управляющий эле-

мент в вашей программе реагировали на такие нажатия кнопки "мы-

ши", нужно определить метод WMLButtonDown, настроенный на сообще-

ние wm_LButtonDown. Затем, когда Windows посылает это сообщение,

ваш объект автоматически вызывает определенный вами метод.

Такие методы называются методами ответа на сообщение. Без

объектно-ориентированного программирования и ObjectWindows вам

пришлось бы написать длинный оператор case для каждого окна и уп-

равлять поступлением этого сообщения, отсортировывать вид сообще-

ния и наконец, решать, что с ним делать. ObjectWindows берет на

себя все эти функции.

Структура программы Windows

При наличии такого множества взаимодействующих элементов

программного обеспечения как DOS, Windows и прикладные программы

полезно знать о том, какие части ваших приложений Windows взаимо-

действуют с окружающей их программной средой. В данном разделе

исследуется структура типичных приложений Windows, написанных в

Borland Pascal with Objects.

Структура Windows

На этапе выполнения функциональные возможности Windows и ее

API сосредоточены в трех библиотечных модулях, вызываемых работа-

ющими в данный момент приложениями. Это следующие модули Windows:

* KERNEL.EXE - управляет распределением памяти и ресурсов,

выполняет планирование и взаимодействие с DOS.

* GDI.EXE - выводит на экран и на принтер графику.

* USER.EXE - работает с окнами, вводом данных от пользовате-

ля и коммуникациями.

Эти модули являются компонентами распространяемой версии

Windows, поэтому пользователи Windows могут найти их на своих

дисках. Поставляемые программы используют эти библиотечные моду-

ли; он не включают их.

Взаимодействие с Windows и DOS

Из-за ограниченного масштаба операционной системы DOS легко

предвидеть, как будет влиять DOS на успешное выполнение ваших

прикладных программ. Тем не менее, программа для DOS работает

благодаря взаимодействию между вашей программой и средствами опе-

рационной системы.

Аналогичное правило действует для программы Windows. Пос-

кольку Windows предлагает значительно большее число функциональ-

ных вызовов операционной системы, взаимодействие между Windows и

вашей программой отследить значительно труднее. Например, чтобы

вывести графику на экран, ваша программа должна вызвать функцию

GDI Windows. Для реакции на нажатие пользователем кнопки "мыши"

программа должна определять метод реакции (ответа) на сообщение.

Ваша программа должна непрерывно взаимодействовать с операционной

системой (DOS + Windows).

Элементарная программа

Традиционным введением в новый язык программирования или

операционную среду является программа, выводящая сообщение

"Hello, Word!", написанная на данном языке или для данной опера-

ционной среды. Это программа содержит количество программного ко-

да, достаточное для вывода на экран строки "Hello, Word!".

Конечно, в Windows нужно сделать значительно больше. Вам

нужно вывести окно, записать в него текст и сделать так, чтобы

окно взаимодействовало с "окружающим миром", по крайней мере вы

должны иметь возможность закрыть окно и выйти. Если вы будете де-

лать все это с самых основ, то даже для выполнения этих элемен-

тарных задач потребуется очень большой объем кода. Например,

программа GENERIC.PAS, содержащаяся на дистрибутивных дисках, вы-

полняя такие элементарные действия, занимает более 100 строк.

Это связано с тем, что предъявляет к прикладной программе

ряд требований, которые та должна удовлетворять перед тем, как

она сможет работать в Windows. Даже простейшая программа требует

большого объема исходного кода. К счастью, программы, написанные

с использованием ObjectWindows, автоматически удовлетворяют этим

требованиям (включая создание и вывод на экран основного окна и

сохранение для приложения описателя окна). Таким образом, прог-

рамма "Hello, Word!" сокращается всего до 16 строк.

program HelloApp;

uses WObjects;

type

THelloWord = object(TApplication)

procedure InitMainWindow; virtual;

end;

procedure THelloWord.InitMainWindow;

begin

MainWindow := New(PWindow,

Init(nil, 'Hello, Borland Pascal'));

end;

var HelloWord: THelloWord;

begin

HelloWord.Init('HelloWord');

HelloWord.Run;

HelloWord.Done;

end.

Действия программы при запуске

При запуске программа ObjectWindows должна сначала получить

от Windows четыре значения и сохранить их в соответствующих гло-

бальных переменных. (Это происходит автоматически, но если бы вы

писали программу, не используя ObjectWindows, то пришлось бы об

этом позаботиться.)

* В HInstance сохраняется описатель экземпляра программы.

* В HPrevInst сохраняется описатель последнего экземпляра

той же прикладной программы.

* В CmdShow записывается целое значение, представляющее на-

чальный режим вывода основного окна. Оно используется для

вызова метода Show.

* В CmdLine записывается командная строка вызова прикладной

программы, включая параметры и имя файла, например

"CALC.EXE /M" или "WORDPROC.EXE LETTER1.DOC".

Как приложение ObjectWindows, программа HelloApp должна

строить и инициализировать объект основного окна. Она может ини-

циализировать только первый экземпляр HelloApp с помощью метода

InitApplication, либо инициализировать каждый экземпляр HelloApp

с помощью метода InitInstance.

HelloApp начинает цикл сообщения, вызывая метод Run. Нако-

нец, она завершается путем освобождения объекта прикладной прог-

раммы с помощью метода Done.

Назначение основного окна

Основное окно прикладной программы - это окно первоначально-

го вывода прикладной программы при ее запуске. Оно отвечает за

представления пользователю списка доступных команд (меню). Во

время сеанса работы с прикладной программой основное окно управ-

ляет интерфейсом прикладной программы и во многих случаях являет-

ся единственной рабочей областью программы, создавая, когда это

требуется, диалоговые окна. Другие, более сложные приложения, мо-

гут использовать в качестве рабочих областей несколько окон. Ког-

да пользователь закрывает основное окно, он инициализирует про-

цесс закрытия прикладной программы.

Цикл разработки прикладной программы

Из-за наличия определенных требований ко многим прикладным

программам Windows (например, инициализация основного окна) вам

будет легче всего начать писать программу, используя существующее

приложение Windows и приспосабливая его для своих нужд. В

ObjectWindows вы можете найти много примеров программ. Выберите

для своего приложения наиболее подходящую.

Используя в Windows интегрированную интерактивную среду раз-

работки программ, вы значительно сократите время разработки. Бла-

годаря многозадачным возможностям Windows, вы можете запустить

IDE, Resource Workshop и свою прикладную программу одновременно.

Поставляемые с Borland Pascal for Windows инструментальные средс-

тва не только облегчают каждую задачу, но и сокращают число задач

при разработке приложения Windows. По существу, это процесс можно

сократить до следующих нескольких шагов:

1. Создание исходного кода программы и включение в программу

имен файлов ресурсов, которые будут использоваться по ди-

рективе {$R имя_файла}.

2. Создание ресурсов для диалоговых окон, меню и т.д.

3. Компиляция программы.

4. Интерактивная отладка программы.

Изучение ObjectWindows

Теперь, когда вы поняли основы программирования в Windows и

имеете начальные сведения об ObjectWindows, можете начинать прог-

раммировать. Начните с чтения "Руководства по программированию с

использованием ObjectWindows" и шаг за шагом изучите, как разра-

батывать приложение ObjectWindows.


Untitled

Borland Pascal. Руководство пользователя
  • Введение
  • Глава 1. Установка и запуск Borland Pascal
  • Глава 2. Что нового в Borland Pascal
  • Глава 3. Основы интегрированной среды для DOS
  • Глава 4. Программирование в интегрированной интерактивной среде для DOS
  • Глава 5. Программирование в интегрированной интерактивнойсреде для Windows
  • Глава 6. Отладка в интегрированной среде
  • Глава 7. Модули Borland Pascal
  • Глава 8. Использование указателей
  • Глава 9. Объектно-ориентированное программирование
  • Глава 10. Взгляд на Windows


Untitled

Глава 1. Установка и запуск Borland Pascal

    • Использование программы Install
    • Программа Install и Windows
    • Запуск Borland Pascal
    • Защищенный режим и память
  • Запуск Borland Pascal for Windows
    • Запуск BP.EXE в расширенном режиме Windows 386
    • Запуск BP.EXE в стандартном режиме Windows
    • Запуск BP.EXE в окне Windows DOS
    • Жидкокристаллические и плазменные экраны
    • Файл README
    • Файлы FILELIST.DOC и HELPME!.DOC
    • Примеры программ


Untitled

Глава 2. Что нового в Borland Pascal

    • Три интегрированных интерактивных среды разработки программ
    • Новые средства IDE
    • Компилятор командной строки, работающий в защищенном режиме
    • Среда разработки программ защищенного режима DOS
    • Динамически компонуемые библиотеки DOS
  • Добавления к языку Паскаль
    • Улучшения в библиотеке исполняющей системы
  • Новые подпрограммы модуля System
    • Новые модули
    • Новые директивы компилятора
    • Усовершенствования компилятора
    • Улучшения в Turbo Vision
    • Улучшения ObjectWindows
    • Новые средства и утилиты


Untitled

Глава 3. Основы интегрированной среды для DOS

    • Запуск IDE
    • Компоненты интегрированной среды
  • Окна IDE
  • Управление окном
  • Строка состояния
  • Диалоговые окна


Untitled

Глава 4. Программирование в интегрированной интерактивной среде для DOS

    • Запуск IDE и выход из нее
    • Параметры запуска
    • Установка параметров
  • Выход из IDE
    • Использование справочной системы Help
    • Перемещение в справочной системе
    • Запрос помощи
    • Копирование примеров исходного кода
    • Загрузка других справочных файлов
    • Выход из справочника Help
    • Запись и редактирование исходного кода
    • Настройка конфигурации редактора
    • Изменение решения: команда Undo
    • Групповая отмена
    • Отмена отмены
  • Работа с блоками текста
    • Выделение блока
    • Вырезание, копирование и вставка блоков
    • Изменение поведения выделенных блоков
  • Поиск
    • Поиск и замена
    • Соответствие пар ограничителей
  • Переход к строке с заданным номером
    • Использование локального меню окна редактирования
  • Выделение синтаксиса
    • Выбор файлов для выделения
    • Запрещение выделения синтаксиса
  • Печать исходного кода
  • Работа с файлами
  • Открытие файлов
    • Открытие файла в позиции курсора
  • Компиляция и выполнение
    • Выбор целевой платформы
  • Компиляция
    • Формирование (Make)
  • Построение (Build)
    • Выполнение
    • Передача программе параметров
  • Параметры компилятора и компоновщика
    • Оптимизация кода
  • Условная компиляция
  • Директивы DEFINE и UNDEF
  • Предопределенные идентификаторы
    • Идентификаторы IFxxx, ELSE и ENDIF
    • Директивы IFDEF и IFNDEF
    • Директива IFOPT
  • Просмотр исходного кода
  • Просмотр объектов
  • Просмотр модулей
  • Просмотр глобальных идентификаторов
  • Просмотр идентификаторов в исходном коде
  • Просмотр функций ObjectBrowser
  • Выполнение в IDE других программ
    • Настройка меню Tools
    • Работа с окном Messages
  • Настройка конфигурации IDE
    • Сохранение рабочей операционной среды
    • Использование файла конфигурации
    • Использование файла оперативной области
  • Управление проектом


Untitled

Глава 5. Программирование в интегрированной интерактивнойсреде для Windows

    • Запуск IDE для Windows
  • Использование оперативной полосы
    • Настройка конфигурации оперативной полосы
  • Использование справочной системы Help
    • Перемещение по справочной системе
    • Запрос помощи
  • Копирование примеров кода
    • Выход из справочной системы
    • Запись и редактирование исходного кода
    • Настройка конфигурации редактора
  • Набор команд
    • Использование редактора
  • Выделение синтаксиса
    • Цветовое выделение текста
    • Использование системных цветов Windows
    • Изменение атрибутов текста
  • Печать исходного кода
  • Работа с файлами
    • Открытие файлов
    • Где находятся файлы?
    • Работа с файлами в другом каталоге
    • Компиляция и выполнение
    • Просмотр исходного кода
  • Просмотр объектов
    • Буквенные символы в ObjectBrowser
    • Фильтры
  • Просмотр глобальных идентификаторов
    • Просмотр идентификаторов в исходном коде
    • Выполнение в IDE других программ
    • Настройка конфигурации IDE


Untitled

Глава 6. Отладка в интегрированной среде

    • Что такое отладка?
    • Какие существуют виды ошибок?
  • Методы отладки
  • Генерация отладочной информации
  • Управление выполнением
  • Что такое шаг?
    • Выполнение программы по шагам
  • Трассировка программы
    • Трассировка или выполнение по шагам?
  • Выполнение больших фрагментов
    • Поиск нужного места
    • Повторное выполнение
    • Отслеживание вывода программы
    • Переключение экранов
    • Окно Output
    • Использование двух мониторов
    • Просмотр значений
  • Что такое выражение?
  • Просмотр выражений
  • Спецификаторы формата в выражениях отладчика
    • Вычисление и модификация
  • Использование точек останова
    • Задание точек останова
    • Отмена точке останова
    • Модификация точек останова
    • Создание условный точек останова
    • Прерывание программы без точек останова


Untitled

Глава 7. Модули Borland Pascal

    • Что такое модуль?
  • Структура модуля
  • Интерфейсная секция
    • Секция реализации
    • Секция инициализации
    • Как используются модули?
    • Ссылки на описания модуля
    • Оператор uses секции реализации
  • Стандартные модули
    • Создание ваших собственных модулей
    • Компиляция модуля
    • Доступность модуля для программы
  • Пример
    • Модули и большие программы
    • Утилита TPUMOVER


Untitled

Глава 8. Использование указателей

    • Для чего используются указатели?
    • Работа с большими объемами данных
    • Работа с данными неизвестного размера
    • Работа с временными буферами данных
    • Работа с несколькими типами данных
    • Связанные списки
    • Что такое указатель?
    • Ссылочный тип
    • Типизированные указатели
    • Разыменование указателей
  • Как использовать указатели?
    • Выделение памяти для динамических переменных
  • Освобождение памяти, выделенной для динамических переменных
    • Процедуры GetMem и FreeMem
  • Проверка объема доступной динамически распределяемой памяти
    • Общие проблемы использования указателей
    • Разыменование неинициализированных указателей
    • Потери динамически распределяемой памяти
    • Управление связанным списком
  • Построение списка
    • Перемещение по списку
    • Освобождение выделенной для списка памяти


Untitled

Глава 9. Объектно-ориентированное программирование

    • Объекты
    • Наследование
  • Объекты: наследующие записи
    • Экземпляры объектных типов
    • Поля объектов
    • Хорошая и плохая техника программирования
  • Методы
    • Совмещенные код и данные
    • Определение методов
    • Область действия метода и параметр Self
    • Поля данных объекта и формальные параметры метода
    • Объекты, экспортируемые модулями
    • Секция private
    • Программирование в "действительном залоге"
  • Инкапсуляция
    • Методы: никакого ухудшения
    • Расширяющиеся объекты
    • Наследование статических методов
  • Виртуальные методы и полиморфизм
    • Раннее связывание против позднего связывания
    • Совместимость типов объектов
  • Полиморфические объекты
    • Виртуальные методы
    • Проверка диапазонов при вызове виртуальных методов
    • Расширяемость объекта
    • Статические методы или виртуальные методы?
    • Динамические объекты
    • Размещение и инициализация с помощью процедуры New
    • Удаление динамических объектов
  • Деструкторы
    • Пример размещения динамического объекта
    • Что же дальше?
    • Заключение


Untitled

Глава 10. Взгляд на Windows

  • Что такое приложение Windows?
    • Преимущества Windows
    • Требования
    • Программные средства
    • Архитектура с управлением по событиям
    • Графика, независимая от устройств
    • Многозадачность
    • Управление памятью
    • Ресурсы
    • Динамическая компоновка
    • Буфер вырезанного изображения
    • Динамический обмен данными
  • Множественный документальный интерфейс
  • Типы данных Windows
    • Объектно-ориентированная работа с окнами
    • Лучший интерфейс с Windows
    • Интерфейсные объекты
    • Абстрагирование функций Windows
    • Автоматизация ответа на сообщения
  • Структура программы Windows
    • Структура Windows
    • Взаимодействие с Windows и DOS
  • Элементарная программа
    • Действия программы при запуске
    • Назначение основного окна
  • Цикл разработки прикладной программы
    • Изучение ObjectWindows


Untitled

Введение

  • Как использовать руководства по Borland Pascal


Untitled

Введение

Borland Pascal with Objects (Паскаль с объектами фирмы

Borland) предназначен для всех тех пользователей, которые хотят

разрабатывать прикладные программы для операционной системы DOS

или операционной среды Windows. Вы можете создавать прикладные

программы, работающие в реальном режиме DOS, Windows или приклад-

ные программы для защищенного режима DOS или Windows. Borland

Pascal предлагает богатую среду программирования, которая делает

разработку программного обеспечения более производительной и бо-

лее приятной. Используя структурированный язык высокого уровня

Паскаль, вы можете писать программы для приложений любого типа и

размера.

Borland Pascal 7.0, оставаясь совместимым с программным ко-

дом, написанным для Turbo Pascal или Turbo Pascal for Windows,

предоставляет вам новые возможности. Исследуя эти возможности

следует учитывать, что этот компилятор Паскаля является быстрым и

эффективным компилятором и принят в качестве общемирового стан-

дарта.

Как использовать руководства по Borland Pascal

Borland Pascal поставляется с одиннадцатью руководствами,

каждое из которых имеет свое назначение.

Примечание: Если раньше вы никогда не работали с прог-

раммным продуктом Turbo Pascal, прочтите руководство поль-

зователя.

"Руководство пользователя" будет для вас полезным, если:

- вы хотите знать, как установить Borland Pascal;

- ранее вы использовали Turbo Pascal или Borland Pascal for

Windows и хотите знать, что нового в этой версии;

- вы хотите узнать, как работать с интегрированной средой

разработки программ Borland (IDE) и использовать ее для

разработки и отладки программ;

- вы хотите узнать о программных модулях и о том, как напи-

сать свой собственный модуль;

- ранее вы не использовали в своих программах указатели или

хотите освежить свои знания об указателях;

- вы не знакомы с объектно-ориентированным программировани-

ем;

- хотите получить начальные сведения об ObjectWindows.

Примечание: Если вы хотите узнать о языке Borland

Pascal, прочтите "Руководство по языку".

"Руководство по языку" посвящено языку Borland Pascal и по-

ясняет как извлечь из него максимум возможного. Используйте "Ру-

ководство по языку", чтобы:

- найти формальное определение языка Borland Pascal, включая

подробные диаграммы синтаксиса, описывающие каждую конс-

трукцию Borland Pascal;

- узнать как использовать библиотеки динамической компоновки

и как написать свою собственную библиотеку;

- изучить организацию библиотек исполняющей системы и их ис-

пользование;

- изучить процедуры, функции, предописанные переменные,

константы и т.д. и узнать о том, что собой представляют

доступные вашим программам библиотеки исполняющей системы;

- исследовать, как программы Borland Pascal использую па-

мять;

- узнать, как Borland Pascal реализует управление програм-

мой;

- узнать об оптимизации кода в Borland Pascal;

- выяснить, как Borland Pascal использует язык ассемблера.

Примечание: При программировании в Borland Pascal в

качестве основного справочника используйте "Справочное ру-

ководство программиста".

"Справочное руководство программиста" представляет собой

справочник со всеми необходимыми вам подробностями. При програм-

мировании держите это руководство рядом с компьютером. Используй-

те "Справочное руководство программиста", если вы хотите:

- узнать о деталях конкретной процедуры, функции, типе или

константе библиотеки исполняющей системы и выяснить, как

их использовать;

- понять, как работают директивы компилятора, что делает

каждая директива компилятора и как пользоваться этими ди-

рективами;

- выяснить, что означает сообщение об ошибке;

- познакомиться с использованием компилятора, работающего в

режиме командной строки;

- просмотреть команды редактора;

- просмотреть краткую справочную информацию по директивам

компилятора;

- ознакомиться со списком зарезервированных слов и стандарт-

ных директив.

Примечание: Чтобы узнать о разработке программ для DOS

с помощью Turbo Vision, используйте "Руководство по прог-

раммированию с использованием Turbo Vision"

"Руководство по программированию с использованием Turbo

Vision" знакомит вас с Turbo Vision и поясняет как с ней рабо-

тать. Turbo Vision - это интегрированная система разработки прик-

ладных программ, позволяющая вам быстро начать объектно-ориенти-

рованное программирование в DOS. Чтобы освоить Turbo Vision, вам

нужно:

- проработать руководство и приобрести некоторые навыки раз-

работки прикладной программы Turbo Vision;

- изучить иерархию Turbo Vision и познакомиться с типами

объектов;

- понять смысл программирования, управляемого событиями, и

что оно за собой влечет;

- использовать справочник по Turbo Vision для нахождения де-

тальной информации об объектах и соответствующих типах,

константах и переменных в иерархии Turbo Vision.

Примечание: Чтобы узнать о том как писать программы

для Windows с помощью ObjectWindows, используйте "Руководс-

тво по программированию с использованием ObjectWindows"

"Руководство по программированию с использованием

ObjectWindows" - это ваше руководство для разработки приложений

Windows с помощью библиотеки ObjectWindows Borland Pascal with

Objects. Чтобы овладеть ObjectWindows, вам понадобится:

- проработать руководство и приобрести некоторые навыки раз-

работки прикладной программы ObjectWindows;

- изучить иерархию ObjectWindows и прочитать о том, какие

задачи могут выполнять объекты ObjectWindows;

- научиться работать в своей программе ObjectWindows с гра-

фикой, ресурсами и данными;

- использовать справочник по ObjectWindows для нахождения

детальной информации об объектах и соответствующих типах,

константах и переменных в иерархии ObjectWindows.

Примечание: Чтобы узнать об инструментальных средс-

твах, которые могут сделать программирование на Паскале еще

более продуктивным, познакомьтесь с "Руководством по инс-

трументальным средствам и утилитам".

"Руководство по инструментальным средствам и утилитам" пояс-

няет как использовать поставляемые с Borland Pascal инструмен-

тальные средства и утилиты. Познакомьтесь с "Руководством по инс-

трументальным средствам и утилитам", если вы хотите:

- узнать о том, как использовать утилиту TPUMOVER для добав-

ления и удаления модулей из библиотеки исполняющей системы

Borland Pascal.

- выяснить, как можно использовать администратор проектов

MAKE;

- использовать утилиту WinSight для проверки сообщений, по-

лучаемых и контролируемых вашим приложением Windows;

- использовать утилиту WinSpector для проверки вашего прило-

жения Windows после получения невосстанавливаемой ошибки

прикладной программы (Unrecoverable Application Error),

чтобы помочь вам выяснить, что здесь неверно;

- прочитать о компиляторе ресурсов Resource Compiler, позво-

ляющем компилировать ваши ресурсы Windows; для создания

ресурсов вы, несомненно, предпочтете использовать пакет

разработчика ресурсов фирмы Borland (Resource Workshop),

но для полноты мы включили компилятор ресурсов;

- узнать о том, как создавать справочные файлы Windows 3.0 и

3.1;

- выяснить, как использовать при работе с инструментальными

средствами режима командной строки резидентную в памяти

справочную систему Borland Pascal - Turbo Help.

Кроме этих книг, специально посвященных Borland Pascal, па-

кет Borland Pascal включает в себя также следующие руководства,

которые можно использовать с Borland Pascal и другими языковыми

средствами Borland:

- "Руководство пользователя по Турбо отладчику";

- "Руководство пользователя по Турбо профилировщику";

- "Руководство пользователя по Турбо Ассемблеру";

- "Краткий справочник по Турбо Ассемблеру".